tests: Set surface and usage for swapchain creation
[platform/upstream/Vulkan-LoaderAndValidationLayers.git] / tests / layer_validation_tests.cpp
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@gmail.com>
14  * Author: Chris Forbes <chrisf@ijw.co.nz>
15  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16  * Author: Mark Lobodzinski <mark@lunarg.com>
17  * Author: Mike Stroyan <mike@LunarG.com>
18  * Author: Tobin Ehlis <tobine@google.com>
19  * Author: Tony Barbour <tony@LunarG.com>
20  * Author: Cody Northrop <cnorthrop@google.com>
21  */
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
40 #define GLM_FORCE_RADIANS
41 #include "glm/glm.hpp"
42 #include <glm/gtc/matrix_transform.hpp>
43
44 #define PARAMETER_VALIDATION_TESTS 1
45 #define MEM_TRACKER_TESTS 1
46 #define OBJ_TRACKER_TESTS 1
47 #define DRAW_STATE_TESTS 1
48 #define THREADING_TESTS 1
49 #define SHADER_CHECKER_TESTS 1
50 #define DEVICE_LIMITS_TESTS 1
51 #define IMAGE_TESTS 1
52
53 //--------------------------------------------------------------------------------------
54 // Mesh and VertexFormat Data
55 //--------------------------------------------------------------------------------------
56 struct Vertex {
57     float posX, posY, posZ, posW; // Position data
58     float r, g, b, a;             // Color
59 };
60
61 #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
62
63 typedef enum _BsoFailSelect {
64     BsoFailNone = 0x00000000,
65     BsoFailLineWidth = 0x00000001,
66     BsoFailDepthBias = 0x00000002,
67     BsoFailViewport = 0x00000004,
68     BsoFailScissor = 0x00000008,
69     BsoFailBlend = 0x00000010,
70     BsoFailDepthBounds = 0x00000020,
71     BsoFailStencilReadMask = 0x00000040,
72     BsoFailStencilWriteMask = 0x00000080,
73     BsoFailStencilReference = 0x00000100,
74     BsoFailCmdClearAttachments = 0x00000200,
75     BsoFailIndexBuffer = 0x00000400,
76 } BsoFailSelect;
77
78 struct vktriangle_vs_uniform {
79     // Must start with MVP
80     float mvp[4][4];
81     float position[3][4];
82     float color[3][4];
83 };
84
85 static const char bindStateVertShaderText[] = "#version 450\n"
86                                               "vec2 vertices[3];\n"
87                                               "out gl_PerVertex {\n"
88                                               "    vec4 gl_Position;\n"
89                                               "};\n"
90                                               "void main() {\n"
91                                               "      vertices[0] = vec2(-1.0, -1.0);\n"
92                                               "      vertices[1] = vec2( 1.0, -1.0);\n"
93                                               "      vertices[2] = vec2( 0.0,  1.0);\n"
94                                               "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
95                                               "}\n";
96
97 static const char bindStateFragShaderText[] = "#version 450\n"
98                                               "\n"
99                                               "layout(location = 0) out vec4 uFragColor;\n"
100                                               "void main(){\n"
101                                               "   uFragColor = vec4(0,1,0,1);\n"
102                                               "}\n";
103
104 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
105                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
106                                                 void *pUserData);
107
108 // ********************************************************
109 // ErrorMonitor Usage:
110 //
111 // Call SetDesiredFailureMsg with a string to be compared against all
112 // encountered log messages. Passing NULL will match all log messages.
113 // logMsg will return true for skipCall only if msg is matched or NULL.
114 //
115 // Call DesiredMsgFound to determine if the desired failure message
116 // was encountered.
117
118 class ErrorMonitor {
119   public:
120     ErrorMonitor() {
121         test_platform_thread_create_mutex(&m_mutex);
122         test_platform_thread_lock_mutex(&m_mutex);
123         m_msgFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT;
124         m_bailout = NULL;
125         m_desiredMsgSet = false;
126         test_platform_thread_unlock_mutex(&m_mutex);
127     }
128
129     ~ErrorMonitor() { test_platform_thread_delete_mutex(&m_mutex); }
130
131     void SetDesiredFailureMsg(VkFlags msgFlags, const char *msgString) {
132         // also discard all collected messages to this point
133         test_platform_thread_lock_mutex(&m_mutex);
134         m_failureMsgs.clear();
135         m_otherMsgs.clear();
136         m_desiredMsgs.insert(msgString);
137         m_msgFound = VK_FALSE;
138         m_msgFlags = msgFlags;
139         m_desiredMsgSet = true;
140         test_platform_thread_unlock_mutex(&m_mutex);
141     }
142
143     VkBool32 CheckForDesiredMsg(const char *msgString) {
144         VkBool32 result = VK_FALSE;
145         test_platform_thread_lock_mutex(&m_mutex);
146         if (m_bailout != NULL) {
147             *m_bailout = true;
148         }
149         string errorString(msgString);
150         bool found_expected = false;
151         for (auto desired_msg : m_desiredMsgs) {
152             if (errorString.find(desired_msg) != string::npos) {
153                 found_expected = true;
154                 m_failureMsgs.insert(errorString);
155                 m_msgFound = VK_TRUE;
156                 result = VK_TRUE;
157                 // We only want one match for each expected error so remove from set here
158                 // Since we're about the break the loop it's ok to remove from set we're iterating over
159                 m_desiredMsgs.erase(desired_msg);
160                 break;
161             }
162         }
163         if (!found_expected) {
164             printf("Unexpected: %s\n", msgString);
165             m_otherMsgs.push_back(errorString);
166         }
167         test_platform_thread_unlock_mutex(&m_mutex);
168         return result;
169     }
170
171     vector<string> GetOtherFailureMsgs(void) { return m_otherMsgs; }
172
173     VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; }
174
175     VkBool32 DesiredMsgFound(void) { return m_msgFound; }
176
177     void SetBailout(bool *bailout) { m_bailout = bailout; }
178
179     void DumpFailureMsgs(void) {
180         vector<string> otherMsgs = GetOtherFailureMsgs();
181         cout << "Other error messages logged for this test were:" << endl;
182         for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) {
183             cout << "     " << *iter << endl;
184         }
185     }
186
187     // Helpers
188
189     // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
190     void ExpectSuccess(VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
191         m_msgFlags = message_flag_mask;
192         // Match ANY message matching specified type
193         SetDesiredFailureMsg(message_flag_mask, "");
194     }
195
196     void VerifyFound() {
197         // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages.
198         if (!DesiredMsgFound()) {
199             DumpFailureMsgs();
200             for (auto desired_msg : m_desiredMsgs) {
201                 FAIL() << "Did not receive expected error '" << desired_msg << "'";
202             }
203         }
204     }
205
206     void VerifyNotFound() {
207         // ExpectSuccess() configured us to match anything. Any error is a failure.
208         if (DesiredMsgFound()) {
209             DumpFailureMsgs();
210             for (auto msg : m_failureMsgs) {
211                 FAIL() << "Expected to succeed but got error: " << msg;
212             }
213         }
214     }
215
216   private:
217     VkFlags m_msgFlags;
218     std::unordered_set<string> m_desiredMsgs;
219     std::unordered_set<string> m_failureMsgs;
220     vector<string> m_otherMsgs;
221     test_platform_thread_mutex m_mutex;
222     bool *m_bailout;
223     VkBool32 m_msgFound;
224     bool m_desiredMsgSet;
225 };
226
227 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
228                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
229                                                 void *pUserData) {
230     ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
231     if (msgFlags & errMonitor->GetMessageFlags()) {
232         return errMonitor->CheckForDesiredMsg(pMsg);
233     }
234     return false;
235 }
236
237 class VkLayerTest : public VkRenderFramework {
238   public:
239     VkResult BeginCommandBuffer(VkCommandBufferObj &commandBuffer);
240     VkResult EndCommandBuffer(VkCommandBufferObj &commandBuffer);
241     void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
242     void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet,
243                                 BsoFailSelect failMask);
244     void GenericDrawPreparation(VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) {
245         GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failMask);
246     }
247
248     /* Convenience functions that use built-in command buffer */
249     VkResult BeginCommandBuffer() { return BeginCommandBuffer(*m_commandBuffer); }
250     VkResult EndCommandBuffer() { return EndCommandBuffer(*m_commandBuffer); }
251     void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
252         m_commandBuffer->Draw(vertexCount, instanceCount, firstVertex, firstInstance);
253     }
254     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
255                      uint32_t firstInstance) {
256         m_commandBuffer->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
257     }
258     void QueueCommandBuffer(bool checkSuccess = true) { m_commandBuffer->QueueCommandBuffer(checkSuccess); }
259     void QueueCommandBuffer(const VkFence &fence) { m_commandBuffer->QueueCommandBuffer(fence); }
260     void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding) {
261         m_commandBuffer->BindVertexBuffer(vertexBuffer, offset, binding);
262     }
263     void BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset) {
264         m_commandBuffer->BindIndexBuffer(indexBuffer, offset);
265     }
266
267   protected:
268     ErrorMonitor *m_errorMonitor;
269     bool m_enableWSI;
270
271     virtual void SetUp() {
272         std::vector<const char *> instance_layer_names;
273         std::vector<const char *> instance_extension_names;
274         std::vector<const char *> device_extension_names;
275
276         instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
277         /*
278          * Since CreateDbgMsgCallback is an instance level extension call
279          * any extension / layer that utilizes that feature also needs
280          * to be enabled at create instance time.
281          */
282         // Use Threading layer first to protect others from
283         // ThreadCommandBufferCollision test
284         instance_layer_names.push_back("VK_LAYER_GOOGLE_threading");
285         instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
286         instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
287         instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
288         instance_layer_names.push_back("VK_LAYER_LUNARG_image");
289         instance_layer_names.push_back("VK_LAYER_LUNARG_swapchain");
290         instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
291
292         if (m_enableWSI) {
293             instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
294             device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
295 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
296 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
297             instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
298 #endif // VK_USE_PLATFORM_ANDROID_KHR
299 #if defined(VK_USE_PLATFORM_MIR_KHR)
300             instance_extension_names.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
301 #endif // VK_USE_PLATFORM_MIR_KHR
302 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
303             instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
304 #endif // VK_USE_PLATFORM_WAYLAND_KHR
305 #if defined(VK_USE_PLATFORM_WIN32_KHR)
306             instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
307 #endif // VK_USE_PLATFORM_WIN32_KHR
308 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
309 #if defined(VK_USE_PLATFORM_XCB_KHR)
310             instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
311 #elif defined(VK_USE_PLATFORM_XLIB_KHR)
312             instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
313 #endif // VK_USE_PLATFORM_XLIB_KHR
314         }
315
316         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
317         this->app_info.pNext = NULL;
318         this->app_info.pApplicationName = "layer_tests";
319         this->app_info.applicationVersion = 1;
320         this->app_info.pEngineName = "unittest";
321         this->app_info.engineVersion = 1;
322         this->app_info.apiVersion = VK_API_VERSION_1_0;
323
324         m_errorMonitor = new ErrorMonitor;
325         InitFramework(instance_layer_names, instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
326     }
327
328     virtual void TearDown() {
329         // Clean up resources before we reset
330         ShutdownFramework();
331         delete m_errorMonitor;
332     }
333
334     VkLayerTest() { m_enableWSI = false; }
335 };
336
337 VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &commandBuffer) {
338     VkResult result;
339
340     result = commandBuffer.BeginCommandBuffer();
341
342     /*
343      * For render test all drawing happens in a single render pass
344      * on a single command buffer.
345      */
346     if (VK_SUCCESS == result && renderPass()) {
347         commandBuffer.BeginRenderPass(renderPassBeginInfo());
348     }
349
350     return result;
351 }
352
353 VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &commandBuffer) {
354     VkResult result;
355
356     if (renderPass()) {
357         commandBuffer.EndRenderPass();
358     }
359
360     result = commandBuffer.EndCommandBuffer();
361
362     return result;
363 }
364
365 void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask) {
366     // Create identity matrix
367     int i;
368     struct vktriangle_vs_uniform data;
369
370     glm::mat4 Projection = glm::mat4(1.0f);
371     glm::mat4 View = glm::mat4(1.0f);
372     glm::mat4 Model = glm::mat4(1.0f);
373     glm::mat4 MVP = Projection * View * Model;
374     const int matrixSize = sizeof(MVP);
375     const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
376
377     memcpy(&data.mvp, &MVP[0][0], matrixSize);
378
379     static const Vertex tri_data[] = {
380         {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)},
381     };
382
383     for (i = 0; i < 3; i++) {
384         data.position[i][0] = tri_data[i].posX;
385         data.position[i][1] = tri_data[i].posY;
386         data.position[i][2] = tri_data[i].posZ;
387         data.position[i][3] = tri_data[i].posW;
388         data.color[i][0] = tri_data[i].r;
389         data.color[i][1] = tri_data[i].g;
390         data.color[i][2] = tri_data[i].b;
391         data.color[i][3] = tri_data[i].a;
392     }
393
394     ASSERT_NO_FATAL_FAILURE(InitViewport());
395
396     VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data,
397                                        VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
398
399     VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
400     VkShaderObj ps(m_device, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
401
402     VkPipelineObj pipelineobj(m_device);
403     pipelineobj.AddColorAttachment();
404     pipelineobj.AddShader(&vs);
405     pipelineobj.AddShader(&ps);
406     if (failMask & BsoFailLineWidth) {
407         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH);
408         VkPipelineInputAssemblyStateCreateInfo ia_state = {};
409         ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
410         ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
411         pipelineobj.SetInputAssembly(&ia_state);
412     }
413     if (failMask & BsoFailDepthBias) {
414         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS);
415         VkPipelineRasterizationStateCreateInfo rs_state = {};
416         rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
417         rs_state.depthBiasEnable = VK_TRUE;
418         rs_state.lineWidth = 1.0f;
419         pipelineobj.SetRasterization(&rs_state);
420     }
421     // Viewport and scissors must stay in synch or other errors will occur than
422     // the ones we want
423     if (failMask & BsoFailViewport) {
424         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
425     }
426     if (failMask & BsoFailScissor) {
427         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
428     }
429     if (failMask & BsoFailBlend) {
430         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
431         VkPipelineColorBlendAttachmentState att_state = {};
432         att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
433         att_state.blendEnable = VK_TRUE;
434         pipelineobj.AddColorAttachment(0, &att_state);
435     }
436     if (failMask & BsoFailDepthBounds) {
437         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
438     }
439     if (failMask & BsoFailStencilReadMask) {
440         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
441     }
442     if (failMask & BsoFailStencilWriteMask) {
443         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
444     }
445     if (failMask & BsoFailStencilReference) {
446         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
447     }
448
449     VkDescriptorSetObj descriptorSet(m_device);
450     descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
451
452     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
453     ASSERT_VK_SUCCESS(BeginCommandBuffer());
454
455     GenericDrawPreparation(pipelineobj, descriptorSet, failMask);
456
457     // render triangle
458     if (failMask & BsoFailIndexBuffer) {
459         // Use DrawIndexed w/o an index buffer bound
460         DrawIndexed(3, 1, 0, 0, 0);
461     } else {
462         Draw(3, 1, 0, 0);
463     }
464
465     if (failMask & BsoFailCmdClearAttachments) {
466         VkClearAttachment color_attachment = {};
467         color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
468         color_attachment.colorAttachment = 1; // Someone who knew what they were doing would use 0 for the index;
469         VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0};
470
471         vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
472     }
473
474     // finalize recording of the command buffer
475     EndCommandBuffer();
476
477     QueueCommandBuffer();
478 }
479
480 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj,
481                                          VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) {
482     if (m_depthStencil->Initialized()) {
483         commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
484     } else {
485         commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
486     }
487
488     commandBuffer->PrepareAttachments();
489     // Make sure depthWriteEnable is set so that Depth fail test will work
490     // correctly
491     // Make sure stencilTestEnable is set so that Stencil fail test will work
492     // correctly
493     VkStencilOpState stencil = {};
494     stencil.failOp = VK_STENCIL_OP_KEEP;
495     stencil.passOp = VK_STENCIL_OP_KEEP;
496     stencil.depthFailOp = VK_STENCIL_OP_KEEP;
497     stencil.compareOp = VK_COMPARE_OP_NEVER;
498
499     VkPipelineDepthStencilStateCreateInfo ds_ci = {};
500     ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
501     ds_ci.pNext = NULL;
502     ds_ci.depthTestEnable = VK_FALSE;
503     ds_ci.depthWriteEnable = VK_TRUE;
504     ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
505     ds_ci.depthBoundsTestEnable = VK_FALSE;
506     if (failMask & BsoFailDepthBounds) {
507         ds_ci.depthBoundsTestEnable = VK_TRUE;
508         ds_ci.maxDepthBounds = 0.0f;
509         ds_ci.minDepthBounds = 0.0f;
510     }
511     ds_ci.stencilTestEnable = VK_TRUE;
512     ds_ci.front = stencil;
513     ds_ci.back = stencil;
514
515     pipelineobj.SetDepthStencil(&ds_ci);
516     pipelineobj.SetViewport(m_viewports);
517     pipelineobj.SetScissor(m_scissors);
518     descriptorSet.CreateVKDescriptorSet(commandBuffer);
519     VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
520     ASSERT_VK_SUCCESS(err);
521     commandBuffer->BindPipeline(pipelineobj);
522     commandBuffer->BindDescriptorSet(descriptorSet);
523 }
524
525 class VkWsiEnabledLayerTest : public VkLayerTest {
526   public:
527   protected:
528     VkWsiEnabledLayerTest() { m_enableWSI = true; }
529 };
530
531 class VkBufferTest {
532   public:
533     enum eTestEnFlags {
534         eDoubleDelete,
535         eInvalidDeviceOffset,
536         eInvalidMemoryOffset,
537         eBindNullBuffer,
538         eFreeInvalidHandle,
539         eNone,
540     };
541
542     enum eTestConditions { eOffsetAlignment = 1 };
543
544     static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) {
545         if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) {
546             return true;
547         }
548         VkDeviceSize offset_limit = 0;
549         if (eInvalidMemoryOffset == aTestFlag) {
550             VkBuffer vulkanBuffer;
551             VkBufferCreateInfo buffer_create_info = {};
552             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
553             buffer_create_info.size = 32;
554             buffer_create_info.usage = aBufferUsage;
555
556             vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer);
557             VkMemoryRequirements memory_reqs = {};
558
559             vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs);
560             vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr);
561             offset_limit = memory_reqs.alignment;
562         } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) {
563             offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment;
564         } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) {
565             offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment;
566         } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) {
567             offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment;
568         }
569         if (eOffsetAlignment < offset_limit) {
570             return true;
571         }
572         return false;
573     }
574
575     // A constructor which performs validation tests within construction.
576     VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone)
577         : AllocateCurrent(false), BoundCurrent(false), CreateCurrent(false), VulkanDevice(aVulkanDevice->device()) {
578
579         if (eBindNullBuffer == aTestFlag) {
580             VulkanMemory = 0;
581             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
582         } else {
583             VkBufferCreateInfo buffer_create_info = {};
584             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
585             buffer_create_info.size = 32;
586             buffer_create_info.usage = aBufferUsage;
587
588             vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer);
589
590             CreateCurrent = true;
591
592             VkMemoryRequirements memory_requirements;
593             vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements);
594
595             VkMemoryAllocateInfo memory_allocate_info = {};
596             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
597             memory_allocate_info.allocationSize = memory_requirements.size;
598             bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info,
599                                                              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
600             if (!pass) {
601                 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
602                 return;
603             }
604
605             vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory);
606             AllocateCurrent = true;
607             // NB: 1 is intentionally an invalid offset value
608             const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag;
609             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0);
610             BoundCurrent = true;
611
612             InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
613         }
614     }
615
616     ~VkBufferTest() {
617         if (CreateCurrent) {
618             vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
619         }
620         if (AllocateCurrent) {
621             if (InvalidDeleteEn) {
622                 union {
623                     VkDeviceMemory device_memory;
624                     unsigned long long index_access;
625                 } bad_index;
626
627                 bad_index.device_memory = VulkanMemory;
628                 bad_index.index_access++;
629
630                 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr);
631             }
632             vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
633         }
634     }
635
636     bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; }
637
638     const VkBuffer &GetBuffer() { return VulkanBuffer; }
639
640     void TestDoubleDestroy() {
641         // Destroy the buffer but leave the flag set, which will cause
642         // the buffer to be destroyed again in the destructor.
643         vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
644     }
645
646   protected:
647     bool AllocateCurrent;
648     bool BoundCurrent;
649     bool CreateCurrent;
650     bool InvalidDeleteEn;
651
652     VkBuffer VulkanBuffer;
653     VkDevice VulkanDevice;
654     VkDeviceMemory VulkanMemory;
655 };
656
657 class VkVerticesObj {
658   public:
659     VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride,
660                   VkDeviceSize aVertexCount, const float *aVerticies)
661         : BoundCurrent(false), AttributeCount(aAttributeCount), BindingCount(aBindingCount), BindId(BindIdGenerator),
662           PipelineVertexInputStateCreateInfo(),
663           VulkanMemoryBuffer(aVulkanDevice, 1, static_cast<int>(aByteStride * aVertexCount),
664                              reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) {
665         BindIdGenerator++; // NB: This can wrap w/misuse
666
667         VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount];
668         VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount];
669
670         PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription;
671         PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount;
672         PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription;
673         PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount;
674         PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
675
676         unsigned i = 0;
677         do {
678             VertexInputAttributeDescription[i].binding = BindId;
679             VertexInputAttributeDescription[i].location = i;
680             VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT;
681             VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride;
682             i++;
683         } while (AttributeCount < i);
684
685         i = 0;
686         do {
687             VertexInputBindingDescription[i].binding = BindId;
688             VertexInputBindingDescription[i].stride = aByteStride;
689             VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
690             i++;
691         } while (BindingCount < i);
692     }
693
694     ~VkVerticesObj() {
695         if (VertexInputAttributeDescription) {
696             delete[] VertexInputAttributeDescription;
697         }
698         if (VertexInputBindingDescription) {
699             delete[] VertexInputBindingDescription;
700         }
701     }
702
703     bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
704         aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount);
705         aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount);
706         return true;
707     }
708
709     void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) {
710         VkDeviceSize *offsetList;
711         unsigned offsetCount;
712
713         if (aOffsetCount) {
714             offsetList = aOffsetList;
715             offsetCount = aOffsetCount;
716         } else {
717             offsetList = new VkDeviceSize[1]();
718             offsetCount = 1;
719         }
720
721         vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList);
722         BoundCurrent = true;
723
724         if (!aOffsetCount) {
725             delete[] offsetList;
726         }
727     }
728
729   protected:
730     static uint32_t BindIdGenerator;
731
732     bool BoundCurrent;
733     unsigned AttributeCount;
734     unsigned BindingCount;
735     uint32_t BindId;
736
737     VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
738     VkVertexInputAttributeDescription *VertexInputAttributeDescription;
739     VkVertexInputBindingDescription *VertexInputBindingDescription;
740     VkConstantBufferObj VulkanMemoryBuffer;
741 };
742
743 uint32_t VkVerticesObj::BindIdGenerator;
744 // ********************************************************************************************************************
745 // ********************************************************************************************************************
746 // ********************************************************************************************************************
747 // ********************************************************************************************************************
748 #if PARAMETER_VALIDATION_TESTS
749 TEST_F(VkLayerTest, RequiredParameter) {
750     TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, "
751                      "pointer, array, and array count parameters");
752
753     ASSERT_NO_FATAL_FAILURE(InitState());
754
755     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL");
756     // Specify NULL for a pointer to a handle
757     // Expected to trigger an error with
758     // parameter_validation::validate_required_pointer
759     vkGetPhysicalDeviceFeatures(gpu(), NULL);
760     m_errorMonitor->VerifyFound();
761
762     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
763                                          "required parameter pQueueFamilyPropertyCount specified as NULL");
764     // Specify NULL for pointer to array count
765     // Expected to trigger an error with parameter_validation::validate_array
766     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
767     m_errorMonitor->VerifyFound();
768
769     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter viewportCount must be greater than 0");
770     // Specify 0 for a required array count
771     // Expected to trigger an error with parameter_validation::validate_array
772     VkViewport view_port = {};
773     m_commandBuffer->SetViewport(0, 0, &view_port);
774     m_errorMonitor->VerifyFound();
775
776     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pViewports specified as NULL");
777     // Specify NULL for a required array
778     // Expected to trigger an error with parameter_validation::validate_array
779     m_commandBuffer->SetViewport(0, 1, NULL);
780     m_errorMonitor->VerifyFound();
781
782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE");
783     // Specify VK_NULL_HANDLE for a required handle
784     // Expected to trigger an error with
785     // parameter_validation::validate_required_handle
786     vkUnmapMemory(device(), VK_NULL_HANDLE);
787     m_errorMonitor->VerifyFound();
788
789     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
790                                          "required parameter pFences[0] specified as VK_NULL_HANDLE");
791     // Specify VK_NULL_HANDLE for a required handle array entry
792     // Expected to trigger an error with
793     // parameter_validation::validate_required_handle_array
794     VkFence fence = VK_NULL_HANDLE;
795     vkResetFences(device(), 1, &fence);
796     m_errorMonitor->VerifyFound();
797
798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL");
799     // Specify NULL for a required struct pointer
800     // Expected to trigger an error with
801     // parameter_validation::validate_struct_type
802     VkDeviceMemory memory = VK_NULL_HANDLE;
803     vkAllocateMemory(device(), NULL, NULL, &memory);
804     m_errorMonitor->VerifyFound();
805
806     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0");
807     // Specify 0 for a required VkFlags parameter
808     // Expected to trigger an error with parameter_validation::validate_flags
809     m_commandBuffer->SetStencilReference(0, 0);
810     m_errorMonitor->VerifyFound();
811
812     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
813     // Specify 0 for a required VkFlags array entry
814     // Expected to trigger an error with
815     // parameter_validation::validate_flags_array
816     VkSemaphore semaphore = VK_NULL_HANDLE;
817     VkPipelineStageFlags stageFlags = 0;
818     VkSubmitInfo submitInfo = {};
819     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
820     submitInfo.waitSemaphoreCount = 1;
821     submitInfo.pWaitSemaphores = &semaphore;
822     submitInfo.pWaitDstStageMask = &stageFlags;
823     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
824     m_errorMonitor->VerifyFound();
825 }
826
827 TEST_F(VkLayerTest, ReservedParameter) {
828     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
829
830     ASSERT_NO_FATAL_FAILURE(InitState());
831
832     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0");
833     // Specify 0 for a reserved VkFlags parameter
834     // Expected to trigger an error with
835     // parameter_validation::validate_reserved_flags
836     VkEvent event_handle = VK_NULL_HANDLE;
837     VkEventCreateInfo event_info = {};
838     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
839     event_info.flags = 1;
840     vkCreateEvent(device(), &event_info, NULL, &event_handle);
841     m_errorMonitor->VerifyFound();
842 }
843
844 TEST_F(VkLayerTest, InvalidStructSType) {
845     TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan "
846                      "structure's sType field");
847
848     ASSERT_NO_FATAL_FAILURE(InitState());
849
850     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be");
851     // Zero struct memory, effectively setting sType to
852     // VK_STRUCTURE_TYPE_APPLICATION_INFO
853     // Expected to trigger an error with
854     // parameter_validation::validate_struct_type
855     VkMemoryAllocateInfo alloc_info = {};
856     VkDeviceMemory memory = VK_NULL_HANDLE;
857     vkAllocateMemory(device(), &alloc_info, NULL, &memory);
858     m_errorMonitor->VerifyFound();
859
860     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be");
861     // Zero struct memory, effectively setting sType to
862     // VK_STRUCTURE_TYPE_APPLICATION_INFO
863     // Expected to trigger an error with
864     // parameter_validation::validate_struct_type_array
865     VkSubmitInfo submit_info = {};
866     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
867     m_errorMonitor->VerifyFound();
868 }
869
870 TEST_F(VkLayerTest, InvalidStructPNext) {
871     TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
872
873     ASSERT_NO_FATAL_FAILURE(InitState());
874
875     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
876     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be
877     // NULL.
878     // Need to pick a function that has no allowed pNext structure types.
879     // Expected to trigger an error with
880     // parameter_validation::validate_struct_pnext
881     VkEvent event = VK_NULL_HANDLE;
882     VkEventCreateInfo event_alloc_info = {};
883     // Zero-initialization will provide the correct sType
884     VkApplicationInfo app_info = {};
885     event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
886     event_alloc_info.pNext = &app_info;
887     vkCreateEvent(device(), &event_alloc_info, NULL, &event);
888     m_errorMonitor->VerifyFound();
889
890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
891                                          " chain includes a structure with unexpected VkStructureType ");
892     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
893     // a function that has allowed pNext structure types and specify
894     // a structure type that is not allowed.
895     // Expected to trigger an error with
896     // parameter_validation::validate_struct_pnext
897     VkDeviceMemory memory = VK_NULL_HANDLE;
898     VkMemoryAllocateInfo memory_alloc_info = {};
899     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
900     memory_alloc_info.pNext = &app_info;
901     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
902     m_errorMonitor->VerifyFound();
903
904     // Positive test to check parameter_validation and unique_objects support
905     // for NV_dedicated_allocation
906     uint32_t extension_count = 0;
907     bool supports_nv_dedicated_allocation = false;
908     VkResult err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, nullptr);
909     ASSERT_VK_SUCCESS(err);
910
911     if (extension_count > 0) {
912         std::vector<VkExtensionProperties> available_extensions(extension_count);
913
914         err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]);
915         ASSERT_VK_SUCCESS(err);
916
917         for (const auto &extension_props : available_extensions) {
918             if (strcmp(extension_props.extensionName, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
919                 supports_nv_dedicated_allocation = true;
920             }
921         }
922     }
923
924     if (supports_nv_dedicated_allocation) {
925         m_errorMonitor->ExpectSuccess();
926
927         VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
928         dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
929         dedicated_buffer_create_info.pNext = nullptr;
930         dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
931
932         uint32_t queue_family_index = 0;
933         VkBufferCreateInfo buffer_create_info = {};
934         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
935         buffer_create_info.pNext = &dedicated_buffer_create_info;
936         buffer_create_info.size = 1024;
937         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
938         buffer_create_info.queueFamilyIndexCount = 1;
939         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
940
941         VkBuffer buffer;
942         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
943         ASSERT_VK_SUCCESS(err);
944
945         VkMemoryRequirements memory_reqs;
946         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
947
948         VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
949         dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
950         dedicated_memory_info.pNext = nullptr;
951         dedicated_memory_info.buffer = buffer;
952         dedicated_memory_info.image = VK_NULL_HANDLE;
953
954         VkMemoryAllocateInfo memory_info = {};
955         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
956         memory_info.pNext = &dedicated_memory_info;
957         memory_info.allocationSize = memory_reqs.size;
958
959         bool pass;
960         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
961         ASSERT_TRUE(pass);
962
963         VkDeviceMemory buffer_memory;
964         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
965         ASSERT_VK_SUCCESS(err);
966
967         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
968         ASSERT_VK_SUCCESS(err);
969
970         vkDestroyBuffer(m_device->device(), buffer, NULL);
971         vkFreeMemory(m_device->device(), buffer_memory, NULL);
972
973         m_errorMonitor->VerifyNotFound();
974     }
975 }
976
977 TEST_F(VkLayerTest, UnrecognizedValue) {
978     TEST_DESCRIPTION("Specify unrecognized Vulkan enumeration, flags, and VkBool32 values");
979
980     ASSERT_NO_FATAL_FAILURE(InitState());
981
982     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end "
983                                                                         "range of the core VkFormat "
984                                                                         "enumeration tokens");
985     // Specify an invalid VkFormat value
986     // Expected to trigger an error with
987     // parameter_validation::validate_ranged_enum
988     VkFormatProperties format_properties;
989     vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
990     m_errorMonitor->VerifyFound();
991
992     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
993     // Specify an invalid VkFlags bitmask value
994     // Expected to trigger an error with parameter_validation::validate_flags
995     VkImageFormatProperties image_format_properties;
996     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
997                                              static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
998     m_errorMonitor->VerifyFound();
999
1000     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
1001     // Specify an invalid VkFlags array entry
1002     // Expected to trigger an error with
1003     // parameter_validation::validate_flags_array
1004     VkSemaphore semaphore = VK_NULL_HANDLE;
1005     VkPipelineStageFlags stage_flags = static_cast<VkPipelineStageFlags>(1 << 25);
1006     VkSubmitInfo submit_info = {};
1007     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1008     submit_info.waitSemaphoreCount = 1;
1009     submit_info.pWaitSemaphores = &semaphore;
1010     submit_info.pWaitDstStageMask = &stage_flags;
1011     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1012     m_errorMonitor->VerifyFound();
1013
1014     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
1015     // Specify an invalid VkBool32 value
1016     // Expected to trigger a warning with
1017     // parameter_validation::validate_bool32
1018     VkSampler sampler = VK_NULL_HANDLE;
1019     VkSamplerCreateInfo sampler_info = {};
1020     sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1021     sampler_info.pNext = NULL;
1022     sampler_info.magFilter = VK_FILTER_NEAREST;
1023     sampler_info.minFilter = VK_FILTER_NEAREST;
1024     sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
1025     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1026     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1027     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1028     sampler_info.mipLodBias = 1.0;
1029     sampler_info.maxAnisotropy = 1;
1030     sampler_info.compareEnable = VK_FALSE;
1031     sampler_info.compareOp = VK_COMPARE_OP_NEVER;
1032     sampler_info.minLod = 1.0;
1033     sampler_info.maxLod = 1.0;
1034     sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
1035     sampler_info.unnormalizedCoordinates = VK_FALSE;
1036     // Not VK_TRUE or VK_FALSE
1037     sampler_info.anisotropyEnable = 3;
1038     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
1039     m_errorMonitor->VerifyFound();
1040 }
1041
1042 TEST_F(VkLayerTest, FailedReturnValue) {
1043     TEST_DESCRIPTION("Check for a message describing a VkResult failure code");
1044
1045     ASSERT_NO_FATAL_FAILURE(InitState());
1046
1047     // Find an unsupported image format
1048     VkFormat unsupported = VK_FORMAT_UNDEFINED;
1049     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
1050         VkFormat format = static_cast<VkFormat>(f);
1051         VkFormatProperties fProps = m_device->format_properties(format);
1052         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
1053             unsupported = format;
1054             break;
1055         }
1056     }
1057
1058     if (unsupported != VK_FORMAT_UNDEFINED) {
1059         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
1060                                              "the requested format is not supported on this device");
1061         // Specify an unsupported VkFormat value to generate a
1062         // VK_ERROR_FORMAT_NOT_SUPPORTED return code
1063         // Expected to trigger a warning from
1064         // parameter_validation::validate_result
1065         VkImageFormatProperties image_format_properties;
1066         VkResult err = vkGetPhysicalDeviceImageFormatProperties(gpu(), unsupported, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
1067                                                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &image_format_properties);
1068         ASSERT_TRUE(err == VK_ERROR_FORMAT_NOT_SUPPORTED);
1069         m_errorMonitor->VerifyFound();
1070     }
1071 }
1072
1073 TEST_F(VkLayerTest, UpdateBufferAlignment) {
1074     TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer");
1075     uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8};
1076
1077     ASSERT_NO_FATAL_FAILURE(InitState());
1078
1079     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1080     vk_testing::Buffer buffer;
1081     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1082
1083     BeginCommandBuffer();
1084     // Introduce failure by using dstOffset that is not multiple of 4
1085     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1086     m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
1087     m_errorMonitor->VerifyFound();
1088
1089     // Introduce failure by using dataSize that is not multiple of 4
1090     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1091     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
1092     m_errorMonitor->VerifyFound();
1093
1094     // Introduce failure by using dataSize that is < 0
1095     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1096                                          "must be greater than zero and less than or equal to 65536");
1097     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, -44, updateData);
1098     m_errorMonitor->VerifyFound();
1099
1100     // Introduce failure by using dataSize that is > 65536
1101     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1102                                          "must be greater than zero and less than or equal to 65536");
1103     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 80000, updateData);
1104     m_errorMonitor->VerifyFound();
1105
1106     EndCommandBuffer();
1107 }
1108
1109 TEST_F(VkLayerTest, FillBufferAlignment) {
1110     TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
1111
1112     ASSERT_NO_FATAL_FAILURE(InitState());
1113
1114     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1115     vk_testing::Buffer buffer;
1116     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1117
1118     BeginCommandBuffer();
1119
1120     // Introduce failure by using dstOffset that is not multiple of 4
1121     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1122     m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
1123     m_errorMonitor->VerifyFound();
1124
1125     // Introduce failure by using size that is not multiple of 4
1126     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1127     m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
1128     m_errorMonitor->VerifyFound();
1129
1130     // Introduce failure by using size that is zero
1131     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero");
1132     m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111);
1133     m_errorMonitor->VerifyFound();
1134
1135     EndCommandBuffer();
1136 }
1137
1138 // This is a positive test. No failures are expected.
1139 TEST_F(VkLayerTest, IgnoreUnrelatedDescriptor) {
1140     TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSet validation code "
1141                      "is ignoring VkWriteDescriptorSet members that are not "
1142                      "related to the descriptor type specified by "
1143                      "VkWriteDescriptorSet::descriptorType.  Correct "
1144                      "validation behavior will result in the test running to "
1145                      "completion without validation errors.");
1146
1147     const uintptr_t invalid_ptr = 0xcdcdcdcd;
1148
1149     ASSERT_NO_FATAL_FAILURE(InitState());
1150
1151     // Image Case
1152     {
1153         m_errorMonitor->ExpectSuccess();
1154
1155         VkImage image;
1156         const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
1157         const int32_t tex_width = 32;
1158         const int32_t tex_height = 32;
1159         VkImageCreateInfo image_create_info = {};
1160         image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1161         image_create_info.pNext = NULL;
1162         image_create_info.imageType = VK_IMAGE_TYPE_2D;
1163         image_create_info.format = tex_format;
1164         image_create_info.extent.width = tex_width;
1165         image_create_info.extent.height = tex_height;
1166         image_create_info.extent.depth = 1;
1167         image_create_info.mipLevels = 1;
1168         image_create_info.arrayLayers = 1;
1169         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1170         image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1171         image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
1172         image_create_info.flags = 0;
1173         VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1174         ASSERT_VK_SUCCESS(err);
1175
1176         VkMemoryRequirements memory_reqs;
1177         VkDeviceMemory image_memory;
1178         bool pass;
1179         VkMemoryAllocateInfo memory_info = {};
1180         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1181         memory_info.pNext = NULL;
1182         memory_info.allocationSize = 0;
1183         memory_info.memoryTypeIndex = 0;
1184         vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
1185         memory_info.allocationSize = memory_reqs.size;
1186         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1187         ASSERT_TRUE(pass);
1188         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
1189         ASSERT_VK_SUCCESS(err);
1190         err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
1191         ASSERT_VK_SUCCESS(err);
1192
1193         VkImageViewCreateInfo image_view_create_info = {};
1194         image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1195         image_view_create_info.image = image;
1196         image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
1197         image_view_create_info.format = tex_format;
1198         image_view_create_info.subresourceRange.layerCount = 1;
1199         image_view_create_info.subresourceRange.baseMipLevel = 0;
1200         image_view_create_info.subresourceRange.levelCount = 1;
1201         image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1202
1203         VkImageView view;
1204         err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
1205         ASSERT_VK_SUCCESS(err);
1206
1207         VkDescriptorPoolSize ds_type_count = {};
1208         ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1209         ds_type_count.descriptorCount = 1;
1210
1211         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1212         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1213         ds_pool_ci.pNext = NULL;
1214         ds_pool_ci.maxSets = 1;
1215         ds_pool_ci.poolSizeCount = 1;
1216         ds_pool_ci.pPoolSizes = &ds_type_count;
1217
1218         VkDescriptorPool ds_pool;
1219         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1220         ASSERT_VK_SUCCESS(err);
1221
1222         VkDescriptorSetLayoutBinding dsl_binding = {};
1223         dsl_binding.binding = 0;
1224         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1225         dsl_binding.descriptorCount = 1;
1226         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1227         dsl_binding.pImmutableSamplers = NULL;
1228
1229         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1230         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1231         ds_layout_ci.pNext = NULL;
1232         ds_layout_ci.bindingCount = 1;
1233         ds_layout_ci.pBindings = &dsl_binding;
1234         VkDescriptorSetLayout ds_layout;
1235         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1236         ASSERT_VK_SUCCESS(err);
1237
1238         VkDescriptorSet descriptor_set;
1239         VkDescriptorSetAllocateInfo alloc_info = {};
1240         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1241         alloc_info.descriptorSetCount = 1;
1242         alloc_info.descriptorPool = ds_pool;
1243         alloc_info.pSetLayouts = &ds_layout;
1244         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1245         ASSERT_VK_SUCCESS(err);
1246
1247         VkDescriptorImageInfo image_info = {};
1248         image_info.imageView = view;
1249         image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1250
1251         VkWriteDescriptorSet descriptor_write;
1252         memset(&descriptor_write, 0, sizeof(descriptor_write));
1253         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1254         descriptor_write.dstSet = descriptor_set;
1255         descriptor_write.dstBinding = 0;
1256         descriptor_write.descriptorCount = 1;
1257         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1258         descriptor_write.pImageInfo = &image_info;
1259
1260         // Set pBufferInfo and pTexelBufferView to invalid values, which should
1261         // be
1262         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
1263         // This will most likely produce a crash if the parameter_validation
1264         // layer
1265         // does not correctly ignore pBufferInfo.
1266         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
1267         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
1268
1269         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1270
1271         m_errorMonitor->VerifyNotFound();
1272
1273         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1274         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1275         vkDestroyImageView(m_device->device(), view, NULL);
1276         vkDestroyImage(m_device->device(), image, NULL);
1277         vkFreeMemory(m_device->device(), image_memory, NULL);
1278     }
1279
1280     // Buffer Case
1281     {
1282         m_errorMonitor->ExpectSuccess();
1283
1284         VkBuffer buffer;
1285         uint32_t queue_family_index = 0;
1286         VkBufferCreateInfo buffer_create_info = {};
1287         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1288         buffer_create_info.size = 1024;
1289         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1290         buffer_create_info.queueFamilyIndexCount = 1;
1291         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
1292
1293         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1294         ASSERT_VK_SUCCESS(err);
1295
1296         VkMemoryRequirements memory_reqs;
1297         VkDeviceMemory buffer_memory;
1298         bool pass;
1299         VkMemoryAllocateInfo memory_info = {};
1300         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1301         memory_info.pNext = NULL;
1302         memory_info.allocationSize = 0;
1303         memory_info.memoryTypeIndex = 0;
1304
1305         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
1306         memory_info.allocationSize = memory_reqs.size;
1307         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1308         ASSERT_TRUE(pass);
1309
1310         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
1311         ASSERT_VK_SUCCESS(err);
1312         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
1313         ASSERT_VK_SUCCESS(err);
1314
1315         VkDescriptorPoolSize ds_type_count = {};
1316         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1317         ds_type_count.descriptorCount = 1;
1318
1319         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1320         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1321         ds_pool_ci.pNext = NULL;
1322         ds_pool_ci.maxSets = 1;
1323         ds_pool_ci.poolSizeCount = 1;
1324         ds_pool_ci.pPoolSizes = &ds_type_count;
1325
1326         VkDescriptorPool ds_pool;
1327         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1328         ASSERT_VK_SUCCESS(err);
1329
1330         VkDescriptorSetLayoutBinding dsl_binding = {};
1331         dsl_binding.binding = 0;
1332         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1333         dsl_binding.descriptorCount = 1;
1334         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1335         dsl_binding.pImmutableSamplers = NULL;
1336
1337         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1338         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1339         ds_layout_ci.pNext = NULL;
1340         ds_layout_ci.bindingCount = 1;
1341         ds_layout_ci.pBindings = &dsl_binding;
1342         VkDescriptorSetLayout ds_layout;
1343         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1344         ASSERT_VK_SUCCESS(err);
1345
1346         VkDescriptorSet descriptor_set;
1347         VkDescriptorSetAllocateInfo alloc_info = {};
1348         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1349         alloc_info.descriptorSetCount = 1;
1350         alloc_info.descriptorPool = ds_pool;
1351         alloc_info.pSetLayouts = &ds_layout;
1352         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1353         ASSERT_VK_SUCCESS(err);
1354
1355         VkDescriptorBufferInfo buffer_info = {};
1356         buffer_info.buffer = buffer;
1357         buffer_info.offset = 0;
1358         buffer_info.range = 1024;
1359
1360         VkWriteDescriptorSet descriptor_write;
1361         memset(&descriptor_write, 0, sizeof(descriptor_write));
1362         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1363         descriptor_write.dstSet = descriptor_set;
1364         descriptor_write.dstBinding = 0;
1365         descriptor_write.descriptorCount = 1;
1366         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1367         descriptor_write.pBufferInfo = &buffer_info;
1368
1369         // Set pImageInfo and pTexelBufferView to invalid values, which should
1370         // be
1371         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
1372         // This will most likely produce a crash if the parameter_validation
1373         // layer
1374         // does not correctly ignore pImageInfo.
1375         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
1376         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
1377
1378         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1379
1380         m_errorMonitor->VerifyNotFound();
1381
1382         vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
1383         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1384         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1385         vkDestroyBuffer(m_device->device(), buffer, NULL);
1386         vkFreeMemory(m_device->device(), buffer_memory, NULL);
1387     }
1388
1389     // Texel Buffer Case
1390     {
1391         m_errorMonitor->ExpectSuccess();
1392
1393         VkBuffer buffer;
1394         uint32_t queue_family_index = 0;
1395         VkBufferCreateInfo buffer_create_info = {};
1396         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1397         buffer_create_info.size = 1024;
1398         buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
1399         buffer_create_info.queueFamilyIndexCount = 1;
1400         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
1401
1402         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1403         ASSERT_VK_SUCCESS(err);
1404
1405         VkMemoryRequirements memory_reqs;
1406         VkDeviceMemory buffer_memory;
1407         bool pass;
1408         VkMemoryAllocateInfo memory_info = {};
1409         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1410         memory_info.pNext = NULL;
1411         memory_info.allocationSize = 0;
1412         memory_info.memoryTypeIndex = 0;
1413
1414         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
1415         memory_info.allocationSize = memory_reqs.size;
1416         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1417         ASSERT_TRUE(pass);
1418
1419         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
1420         ASSERT_VK_SUCCESS(err);
1421         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
1422         ASSERT_VK_SUCCESS(err);
1423
1424         VkBufferViewCreateInfo buff_view_ci = {};
1425         buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
1426         buff_view_ci.buffer = buffer;
1427         buff_view_ci.format = VK_FORMAT_R8_UNORM;
1428         buff_view_ci.range = VK_WHOLE_SIZE;
1429         VkBufferView buffer_view;
1430         err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
1431
1432         VkDescriptorPoolSize ds_type_count = {};
1433         ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1434         ds_type_count.descriptorCount = 1;
1435
1436         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1437         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1438         ds_pool_ci.pNext = NULL;
1439         ds_pool_ci.maxSets = 1;
1440         ds_pool_ci.poolSizeCount = 1;
1441         ds_pool_ci.pPoolSizes = &ds_type_count;
1442
1443         VkDescriptorPool ds_pool;
1444         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1445         ASSERT_VK_SUCCESS(err);
1446
1447         VkDescriptorSetLayoutBinding dsl_binding = {};
1448         dsl_binding.binding = 0;
1449         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1450         dsl_binding.descriptorCount = 1;
1451         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1452         dsl_binding.pImmutableSamplers = NULL;
1453
1454         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1455         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1456         ds_layout_ci.pNext = NULL;
1457         ds_layout_ci.bindingCount = 1;
1458         ds_layout_ci.pBindings = &dsl_binding;
1459         VkDescriptorSetLayout ds_layout;
1460         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1461         ASSERT_VK_SUCCESS(err);
1462
1463         VkDescriptorSet descriptor_set;
1464         VkDescriptorSetAllocateInfo alloc_info = {};
1465         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1466         alloc_info.descriptorSetCount = 1;
1467         alloc_info.descriptorPool = ds_pool;
1468         alloc_info.pSetLayouts = &ds_layout;
1469         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1470         ASSERT_VK_SUCCESS(err);
1471
1472         VkWriteDescriptorSet descriptor_write;
1473         memset(&descriptor_write, 0, sizeof(descriptor_write));
1474         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1475         descriptor_write.dstSet = descriptor_set;
1476         descriptor_write.dstBinding = 0;
1477         descriptor_write.descriptorCount = 1;
1478         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1479         descriptor_write.pTexelBufferView = &buffer_view;
1480
1481         // Set pImageInfo and pBufferInfo to invalid values, which should be
1482         //  ignored for descriptorType ==
1483         //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
1484         // This will most likely produce a crash if the parameter_validation
1485         // layer
1486         // does not correctly ignore pImageInfo and pBufferInfo.
1487         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
1488         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
1489
1490         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1491
1492         m_errorMonitor->VerifyNotFound();
1493
1494         vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
1495         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1496         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1497         vkDestroyBufferView(m_device->device(), buffer_view, NULL);
1498         vkDestroyBuffer(m_device->device(), buffer, NULL);
1499         vkFreeMemory(m_device->device(), buffer_memory, NULL);
1500     }
1501 }
1502
1503 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
1504     VkResult err;
1505
1506     TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a "
1507                      "pipeline when this feature is not enabled.");
1508
1509     ASSERT_NO_FATAL_FAILURE(InitState());
1510     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1511
1512     std::vector<const char *> device_extension_names;
1513     auto features = m_device->phy().features();
1514     // Artificially disable support for non-solid fill modes
1515     features.fillModeNonSolid = false;
1516     // The sacrificial device object
1517     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
1518
1519     VkRenderpassObj render_pass(&test_device);
1520
1521     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
1522     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1523     pipeline_layout_ci.setLayoutCount = 0;
1524     pipeline_layout_ci.pSetLayouts = NULL;
1525
1526     VkPipelineLayout pipeline_layout;
1527     err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1528     ASSERT_VK_SUCCESS(err);
1529
1530     VkPipelineRasterizationStateCreateInfo rs_ci = {};
1531     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1532     rs_ci.pNext = nullptr;
1533     rs_ci.lineWidth = 1.0f;
1534     rs_ci.rasterizerDiscardEnable = true;
1535
1536     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1537     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1538
1539     // Set polygonMode to unsupported value POINT, should fail
1540     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1541                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
1542     {
1543         VkPipelineObj pipe(&test_device);
1544         pipe.AddShader(&vs);
1545         pipe.AddShader(&fs);
1546         pipe.AddColorAttachment();
1547         // Introduce failure by setting unsupported polygon mode
1548         rs_ci.polygonMode = VK_POLYGON_MODE_POINT;
1549         pipe.SetRasterization(&rs_ci);
1550         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1551     }
1552     m_errorMonitor->VerifyFound();
1553
1554     // Try again with polygonMode=LINE, should fail
1555     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1556                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
1557     {
1558         VkPipelineObj pipe(&test_device);
1559         pipe.AddShader(&vs);
1560         pipe.AddShader(&fs);
1561         pipe.AddColorAttachment();
1562         // Introduce failure by setting unsupported polygon mode
1563         rs_ci.polygonMode = VK_POLYGON_MODE_LINE;
1564         pipe.SetRasterization(&rs_ci);
1565         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1566     }
1567     m_errorMonitor->VerifyFound();
1568
1569     // Try again with polygonMode=FILL. No error is expected
1570     m_errorMonitor->ExpectSuccess();
1571     {
1572         VkPipelineObj pipe(&test_device);
1573         pipe.AddShader(&vs);
1574         pipe.AddShader(&fs);
1575         pipe.AddColorAttachment();
1576         // Set polygonMode to a good value
1577         rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
1578         pipe.SetRasterization(&rs_ci);
1579         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1580     }
1581     m_errorMonitor->VerifyNotFound();
1582
1583     vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL);
1584 }
1585
1586 #endif // PARAMETER_VALIDATION_TESTS
1587
1588 #if MEM_TRACKER_TESTS
1589 #if 0
1590 TEST_F(VkLayerTest, CallResetCommandBufferBeforeCompletion)
1591 {
1592     vk_testing::Fence testFence;
1593     VkFenceCreateInfo fenceInfo = {};
1594     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1595     fenceInfo.pNext = NULL;
1596     fenceInfo.flags = 0;
1597
1598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting CB");
1599
1600     ASSERT_NO_FATAL_FAILURE(InitState());
1601
1602     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1603     vk_testing::Buffer buffer;
1604     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1605
1606     BeginCommandBuffer();
1607     m_commandBuffer->FillBuffer(buffer.handle(), 0, 4, 0x11111111);
1608     EndCommandBuffer();
1609
1610     testFence.init(*m_device, fenceInfo);
1611
1612     // Bypass framework since it does the waits automatically
1613     VkResult err = VK_SUCCESS;
1614     VkSubmitInfo submit_info;
1615     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1616     submit_info.pNext = NULL;
1617     submit_info.waitSemaphoreCount = 0;
1618     submit_info.pWaitSemaphores = NULL;
1619     submit_info.pWaitDstStageMask = NULL;
1620     submit_info.commandBufferCount = 1;
1621     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1622     submit_info.signalSemaphoreCount = 0;
1623     submit_info.pSignalSemaphores = NULL;
1624
1625     err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1626     ASSERT_VK_SUCCESS( err );
1627
1628     // Introduce failure by calling begin again before checking fence
1629     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
1630
1631     m_errorMonitor->VerifyFound();
1632 }
1633
1634 TEST_F(VkLayerTest, CallBeginCommandBufferBeforeCompletion)
1635 {
1636     vk_testing::Fence testFence;
1637     VkFenceCreateInfo fenceInfo = {};
1638     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1639     fenceInfo.pNext = NULL;
1640     fenceInfo.flags = 0;
1641
1642     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active CB");
1643
1644     ASSERT_NO_FATAL_FAILURE(InitState());
1645     ASSERT_NO_FATAL_FAILURE(InitViewport());
1646     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1647
1648     BeginCommandBuffer();
1649     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
1650     EndCommandBuffer();
1651
1652     testFence.init(*m_device, fenceInfo);
1653
1654     // Bypass framework since it does the waits automatically
1655     VkResult err = VK_SUCCESS;
1656     VkSubmitInfo submit_info;
1657     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1658     submit_info.pNext = NULL;
1659     submit_info.waitSemaphoreCount = 0;
1660     submit_info.pWaitSemaphores = NULL;
1661     submit_info.pWaitDstStageMask = NULL;
1662     submit_info.commandBufferCount = 1;
1663     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1664     submit_info.signalSemaphoreCount = 0;
1665     submit_info.pSignalSemaphores = NULL;
1666
1667     err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1668     ASSERT_VK_SUCCESS( err );
1669
1670     VkCommandBufferInheritanceInfo hinfo = {};
1671     VkCommandBufferBeginInfo info = {};
1672     info.flags       = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1673     info.sType       = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1674     info.renderPass  = VK_NULL_HANDLE;
1675     info.subpass     = 0;
1676     info.framebuffer = VK_NULL_HANDLE;
1677     info.occlusionQueryEnable = VK_FALSE;
1678     info.queryFlags = 0;
1679     info.pipelineStatistics = 0;
1680
1681     // Introduce failure by calling BCB again before checking fence
1682     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
1683
1684     m_errorMonitor->VerifyFound();
1685 }
1686 #endif
1687
1688 // This is a positive test. No failures are expected.
1689 TEST_F(VkLayerTest, TestAliasedMemoryTracking) {
1690     VkResult err;
1691     bool pass;
1692
1693     TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
1694                      "the buffer, create an image, and bind the same memory to "
1695                      "it");
1696
1697     m_errorMonitor->ExpectSuccess();
1698
1699     ASSERT_NO_FATAL_FAILURE(InitState());
1700
1701     VkBuffer buffer;
1702     VkImage image;
1703     VkDeviceMemory mem;
1704     VkMemoryRequirements mem_reqs;
1705
1706     VkBufferCreateInfo buf_info = {};
1707     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1708     buf_info.pNext = NULL;
1709     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1710     buf_info.size = 256;
1711     buf_info.queueFamilyIndexCount = 0;
1712     buf_info.pQueueFamilyIndices = NULL;
1713     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1714     buf_info.flags = 0;
1715     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1716     ASSERT_VK_SUCCESS(err);
1717
1718     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
1719
1720     VkMemoryAllocateInfo alloc_info = {};
1721     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1722     alloc_info.pNext = NULL;
1723     alloc_info.memoryTypeIndex = 0;
1724
1725     // Ensure memory is big enough for both bindings
1726     alloc_info.allocationSize = 0x10000;
1727
1728     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1729     if (!pass) {
1730         vkDestroyBuffer(m_device->device(), buffer, NULL);
1731         return;
1732     }
1733
1734     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1735     ASSERT_VK_SUCCESS(err);
1736
1737     uint8_t *pData;
1738     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1739     ASSERT_VK_SUCCESS(err);
1740
1741     memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
1742
1743     vkUnmapMemory(m_device->device(), mem);
1744
1745     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
1746     ASSERT_VK_SUCCESS(err);
1747
1748     // NOW, destroy the buffer. Obviously, the resource no longer occupies this
1749     // memory. In fact, it was never used by the GPU.
1750     // Just be be sure, wait for idle.
1751     vkDestroyBuffer(m_device->device(), buffer, NULL);
1752     vkDeviceWaitIdle(m_device->device());
1753
1754     VkImageCreateInfo image_create_info = {};
1755     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1756     image_create_info.pNext = NULL;
1757     image_create_info.imageType = VK_IMAGE_TYPE_2D;
1758     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1759     image_create_info.extent.width = 64;
1760     image_create_info.extent.height = 64;
1761     image_create_info.extent.depth = 1;
1762     image_create_info.mipLevels = 1;
1763     image_create_info.arrayLayers = 1;
1764     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1765     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
1766     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1767     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1768     image_create_info.queueFamilyIndexCount = 0;
1769     image_create_info.pQueueFamilyIndices = NULL;
1770     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1771     image_create_info.flags = 0;
1772
1773     VkMemoryAllocateInfo mem_alloc = {};
1774     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1775     mem_alloc.pNext = NULL;
1776     mem_alloc.allocationSize = 0;
1777     mem_alloc.memoryTypeIndex = 0;
1778
1779     /* Create a mappable image.  It will be the texture if linear images are ok
1780     * to be textures or it will be the staging image if they are not.
1781     */
1782     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1783     ASSERT_VK_SUCCESS(err);
1784
1785     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
1786
1787     mem_alloc.allocationSize = mem_reqs.size;
1788
1789     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1790     if (!pass) {
1791         vkDestroyImage(m_device->device(), image, NULL);
1792         return;
1793     }
1794
1795     // VALIDATION FAILURE:
1796     err = vkBindImageMemory(m_device->device(), image, mem, 0);
1797     ASSERT_VK_SUCCESS(err);
1798
1799     m_errorMonitor->VerifyNotFound();
1800
1801     vkFreeMemory(m_device->device(), mem, NULL);
1802     vkDestroyBuffer(m_device->device(), buffer, NULL);
1803     vkDestroyImage(m_device->device(), image, NULL);
1804 }
1805
1806 TEST_F(VkLayerTest, InvalidMemoryAliasing) {
1807     TEST_DESCRIPTION("Create a buffer and image, allocate memory, and bind the "
1808                      "buffer and image to memory such that they will alias.");
1809     VkResult err;
1810     bool pass;
1811     ASSERT_NO_FATAL_FAILURE(InitState());
1812
1813     VkBuffer buffer, buffer2;
1814     VkImage image;
1815     VkImage image2;
1816     VkDeviceMemory mem;     // buffer will be bound first
1817     VkDeviceMemory mem_img; // image bound first
1818     VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
1819
1820     VkBufferCreateInfo buf_info = {};
1821     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1822     buf_info.pNext = NULL;
1823     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1824     buf_info.size = 256;
1825     buf_info.queueFamilyIndexCount = 0;
1826     buf_info.pQueueFamilyIndices = NULL;
1827     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1828     buf_info.flags = 0;
1829     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1830     ASSERT_VK_SUCCESS(err);
1831
1832     vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs);
1833
1834     VkImageCreateInfo image_create_info = {};
1835     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1836     image_create_info.pNext = NULL;
1837     image_create_info.imageType = VK_IMAGE_TYPE_2D;
1838     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1839     image_create_info.extent.width = 64;
1840     image_create_info.extent.height = 64;
1841     image_create_info.extent.depth = 1;
1842     image_create_info.mipLevels = 1;
1843     image_create_info.arrayLayers = 1;
1844     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1845     // Image tiling must be optimal to trigger error when aliasing linear buffer
1846     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1847     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1848     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1849     image_create_info.queueFamilyIndexCount = 0;
1850     image_create_info.pQueueFamilyIndices = NULL;
1851     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1852     image_create_info.flags = 0;
1853
1854     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1855     ASSERT_VK_SUCCESS(err);
1856     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
1857     ASSERT_VK_SUCCESS(err);
1858
1859     vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
1860
1861     VkMemoryAllocateInfo alloc_info = {};
1862     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1863     alloc_info.pNext = NULL;
1864     alloc_info.memoryTypeIndex = 0;
1865     // Ensure memory is big enough for both bindings
1866     alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size;
1867     pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info,
1868                                            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1869     if (!pass) {
1870         vkDestroyBuffer(m_device->device(), buffer, NULL);
1871         vkDestroyImage(m_device->device(), image, NULL);
1872         return;
1873     }
1874     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1875     ASSERT_VK_SUCCESS(err);
1876     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
1877     ASSERT_VK_SUCCESS(err);
1878
1879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is aliased with linear buffer 0x");
1880     // VALIDATION FAILURE due to image mapping overlapping buffer mapping
1881     err = vkBindImageMemory(m_device->device(), image, mem, 0);
1882     m_errorMonitor->VerifyFound();
1883
1884     // Now correctly bind image2 to second mem allocation before incorrectly
1885     // aliasing buffer2
1886     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2);
1887     ASSERT_VK_SUCCESS(err);
1888     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img);
1889     ASSERT_VK_SUCCESS(err);
1890     err = vkBindImageMemory(m_device->device(), image2, mem_img, 0);
1891     ASSERT_VK_SUCCESS(err);
1892     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is aliased with non-linear image 0x");
1893     err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0);
1894     m_errorMonitor->VerifyFound();
1895
1896     vkDestroyBuffer(m_device->device(), buffer, NULL);
1897     vkDestroyBuffer(m_device->device(), buffer2, NULL);
1898     vkDestroyImage(m_device->device(), image, NULL);
1899     vkDestroyImage(m_device->device(), image2, NULL);
1900     vkFreeMemory(m_device->device(), mem, NULL);
1901     vkFreeMemory(m_device->device(), mem_img, NULL);
1902 }
1903
1904 TEST_F(VkLayerTest, InvalidMemoryMapping) {
1905     TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");
1906     VkResult err;
1907     bool pass;
1908     ASSERT_NO_FATAL_FAILURE(InitState());
1909
1910     VkBuffer buffer;
1911     VkDeviceMemory mem;
1912     VkMemoryRequirements mem_reqs;
1913
1914     VkBufferCreateInfo buf_info = {};
1915     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1916     buf_info.pNext = NULL;
1917     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1918     buf_info.size = 256;
1919     buf_info.queueFamilyIndexCount = 0;
1920     buf_info.pQueueFamilyIndices = NULL;
1921     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1922     buf_info.flags = 0;
1923     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1924     ASSERT_VK_SUCCESS(err);
1925
1926     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
1927     VkMemoryAllocateInfo alloc_info = {};
1928     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1929     alloc_info.pNext = NULL;
1930     alloc_info.memoryTypeIndex = 0;
1931
1932     // Ensure memory is big enough for both bindings
1933     static const VkDeviceSize allocation_size = 0x10000;
1934     alloc_info.allocationSize = allocation_size;
1935     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1936     if (!pass) {
1937         vkDestroyBuffer(m_device->device(), buffer, NULL);
1938         return;
1939     }
1940     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1941     ASSERT_VK_SUCCESS(err);
1942
1943     uint8_t *pData;
1944     // Attempt to map memory size 0 is invalid
1945     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero");
1946     err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData);
1947     m_errorMonitor->VerifyFound();
1948     // Map memory twice
1949     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1950     ASSERT_VK_SUCCESS(err);
1951     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1952                                          "VkMapMemory: Attempting to map memory on an already-mapped object ");
1953     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1954     m_errorMonitor->VerifyFound();
1955
1956     // Unmap the memory to avoid re-map error
1957     vkUnmapMemory(m_device->device(), mem);
1958     // overstep allocation with VK_WHOLE_SIZE
1959     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1960                                          " with size of VK_WHOLE_SIZE oversteps total array size 0x");
1961     err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData);
1962     m_errorMonitor->VerifyFound();
1963     // overstep allocation w/o VK_WHOLE_SIZE
1964     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x");
1965     err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData);
1966     m_errorMonitor->VerifyFound();
1967     // Now error due to unmapping memory that's not mapped
1968     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: ");
1969     vkUnmapMemory(m_device->device(), mem);
1970     m_errorMonitor->VerifyFound();
1971     // Now map memory and cause errors due to flushing invalid ranges
1972     err = vkMapMemory(m_device->device(), mem, 16, VK_WHOLE_SIZE, 0, (void **)&pData);
1973     ASSERT_VK_SUCCESS(err);
1974     VkMappedMemoryRange mmr = {};
1975     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1976     mmr.memory = mem;
1977     mmr.offset = 15; // Error b/c offset less than offset of mapped mem
1978     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") is less than Memory Object's offset (");
1979     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
1980     m_errorMonitor->VerifyFound();
1981     // Now flush range that oversteps mapped range
1982     vkUnmapMemory(m_device->device(), mem);
1983     err = vkMapMemory(m_device->device(), mem, 0, 256, 0, (void **)&pData);
1984     ASSERT_VK_SUCCESS(err);
1985     mmr.offset = 16;
1986     mmr.size = 256; // flushing bounds (272) exceed mapped bounds (256)
1987     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") exceeds the Memory Object's upper-bound (");
1988     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
1989     m_errorMonitor->VerifyFound();
1990
1991     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
1992                                            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
1993     if (!pass) {
1994         vkFreeMemory(m_device->device(), mem, NULL);
1995         vkDestroyBuffer(m_device->device(), buffer, NULL);
1996         return;
1997     }
1998     // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of
1999     //  MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver()
2000
2001     vkDestroyBuffer(m_device->device(), buffer, NULL);
2002     vkFreeMemory(m_device->device(), mem, NULL);
2003 }
2004
2005 TEST_F(VkLayerTest, NonCoherentMemoryMapping) {
2006
2007     TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory "
2008                      "mapping while using VK_WHOLE_SIZE does not cause access "
2009                      "violations");
2010     VkResult err;
2011     uint8_t *pData;
2012     ASSERT_NO_FATAL_FAILURE(InitState());
2013
2014     VkDeviceMemory mem;
2015     VkMemoryRequirements mem_reqs;
2016     mem_reqs.memoryTypeBits = 0xFFFFFFFF;
2017     VkMemoryAllocateInfo alloc_info = {};
2018     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2019     alloc_info.pNext = NULL;
2020     alloc_info.memoryTypeIndex = 0;
2021
2022     static const VkDeviceSize allocation_size = 0x1000;
2023     alloc_info.allocationSize = allocation_size;
2024
2025     // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
2026     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
2027                                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2028     if (!pass) {
2029         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
2030                                                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2031                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2032         if (!pass) {
2033             pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
2034                                                    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
2035                                                        VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2036                                                    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2037             if (!pass) {
2038                 return;
2039             }
2040         }
2041     }
2042
2043     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2044     ASSERT_VK_SUCCESS(err);
2045
2046     // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire
2047     // mapped range
2048     m_errorMonitor->ExpectSuccess();
2049     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
2050     ASSERT_VK_SUCCESS(err);
2051     VkMappedMemoryRange mmr = {};
2052     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2053     mmr.memory = mem;
2054     mmr.offset = 0;
2055     mmr.size = VK_WHOLE_SIZE;
2056     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2057     ASSERT_VK_SUCCESS(err);
2058     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2059     ASSERT_VK_SUCCESS(err);
2060     m_errorMonitor->VerifyNotFound();
2061     vkUnmapMemory(m_device->device(), mem);
2062
2063     // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire
2064     // mapped range
2065     m_errorMonitor->ExpectSuccess();
2066     err = vkMapMemory(m_device->device(), mem, 13, VK_WHOLE_SIZE, 0, (void **)&pData);
2067     ASSERT_VK_SUCCESS(err);
2068     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2069     mmr.memory = mem;
2070     mmr.offset = 13;
2071     mmr.size = VK_WHOLE_SIZE;
2072     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2073     ASSERT_VK_SUCCESS(err);
2074     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2075     ASSERT_VK_SUCCESS(err);
2076     m_errorMonitor->VerifyNotFound();
2077     vkUnmapMemory(m_device->device(), mem);
2078
2079     // Map with prime offset and size
2080     // Flush/Invalidate subrange of mapped area with prime offset and size
2081     m_errorMonitor->ExpectSuccess();
2082     err = vkMapMemory(m_device->device(), mem, allocation_size - 137, 109, 0, (void **)&pData);
2083     ASSERT_VK_SUCCESS(err);
2084     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2085     mmr.memory = mem;
2086     mmr.offset = allocation_size - 107;
2087     mmr.size = 61;
2088     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2089     ASSERT_VK_SUCCESS(err);
2090     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2091     ASSERT_VK_SUCCESS(err);
2092     m_errorMonitor->VerifyNotFound();
2093     vkUnmapMemory(m_device->device(), mem);
2094
2095     // Map without offset and flush WHOLE_SIZE with two separate offsets
2096     m_errorMonitor->ExpectSuccess();
2097     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
2098     ASSERT_VK_SUCCESS(err);
2099     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2100     mmr.memory = mem;
2101     mmr.offset = allocation_size - 100;
2102     mmr.size = VK_WHOLE_SIZE;
2103     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2104     ASSERT_VK_SUCCESS(err);
2105     mmr.offset = allocation_size - 200;
2106     mmr.size = VK_WHOLE_SIZE;
2107     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2108     ASSERT_VK_SUCCESS(err);
2109     m_errorMonitor->VerifyNotFound();
2110     vkUnmapMemory(m_device->device(), mem);
2111
2112     vkFreeMemory(m_device->device(), mem, NULL);
2113 }
2114
2115 TEST_F(VkLayerTest, EnableWsiBeforeUse) {
2116     VkResult err;
2117     bool pass;
2118
2119     // FIXME: After we turn on this code for non-Linux platforms, uncomment the
2120     // following declaration (which is temporarily being moved below):
2121     //    VkSurfaceKHR surface = VK_NULL_HANDLE;
2122     VkSwapchainKHR swapchain = VK_NULL_HANDLE;
2123     VkSwapchainCreateInfoKHR swapchain_create_info = {};
2124     uint32_t swapchain_image_count = 0;
2125     //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
2126     uint32_t image_index = 0;
2127     //    VkPresentInfoKHR present_info = {};
2128
2129     ASSERT_NO_FATAL_FAILURE(InitState());
2130
2131 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
2132 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
2133     // Use the functions from the VK_KHR_android_surface extension without
2134     // enabling that extension:
2135
2136     // Create a surface:
2137     VkAndroidSurfaceCreateInfoKHR android_create_info = {};
2138     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2139     err = vkCreateAndroidSurfaceKHR(instance(), &android_create_info, NULL, &surface);
2140     pass = (err != VK_SUCCESS);
2141     ASSERT_TRUE(pass);
2142     m_errorMonitor->VerifyFound();
2143 #endif // VK_USE_PLATFORM_ANDROID_KHR
2144
2145 #if defined(VK_USE_PLATFORM_MIR_KHR)
2146     // Use the functions from the VK_KHR_mir_surface extension without enabling
2147     // that extension:
2148
2149     // Create a surface:
2150     VkMirSurfaceCreateInfoKHR mir_create_info = {};
2151     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2152     err = vkCreateMirSurfaceKHR(instance(), &mir_create_info, NULL, &surface);
2153     pass = (err != VK_SUCCESS);
2154     ASSERT_TRUE(pass);
2155     m_errorMonitor->VerifyFound();
2156
2157     // Tell whether an mir_connection supports presentation:
2158     MirConnection *mir_connection = NULL;
2159     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2160     vkGetPhysicalDeviceMirPresentationSupportKHR(gpu(), 0, mir_connection, visual_id);
2161     m_errorMonitor->VerifyFound();
2162 #endif // VK_USE_PLATFORM_MIR_KHR
2163
2164 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
2165     // Use the functions from the VK_KHR_wayland_surface extension without
2166     // enabling that extension:
2167
2168     // Create a surface:
2169     VkWaylandSurfaceCreateInfoKHR wayland_create_info = {};
2170     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2171     err = vkCreateWaylandSurfaceKHR(instance(), &wayland_create_info, NULL, &surface);
2172     pass = (err != VK_SUCCESS);
2173     ASSERT_TRUE(pass);
2174     m_errorMonitor->VerifyFound();
2175
2176     // Tell whether an wayland_display supports presentation:
2177     struct wl_display wayland_display = {};
2178     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2179     vkGetPhysicalDeviceWaylandPresentationSupportKHR(gpu(), 0, &wayland_display);
2180     m_errorMonitor->VerifyFound();
2181 #endif // VK_USE_PLATFORM_WAYLAND_KHR
2182 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
2183
2184 #if defined(VK_USE_PLATFORM_WIN32_KHR)
2185     // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED
2186     // TO NON-LINUX PLATFORMS:
2187     VkSurfaceKHR surface = VK_NULL_HANDLE;
2188     // Use the functions from the VK_KHR_win32_surface extension without
2189     // enabling that extension:
2190
2191     // Create a surface:
2192     VkWin32SurfaceCreateInfoKHR win32_create_info = {};
2193     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2194     err = vkCreateWin32SurfaceKHR(instance(), &win32_create_info, NULL, &surface);
2195     pass = (err != VK_SUCCESS);
2196     ASSERT_TRUE(pass);
2197     m_errorMonitor->VerifyFound();
2198
2199     // Tell whether win32 supports presentation:
2200     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2201     vkGetPhysicalDeviceWin32PresentationSupportKHR(gpu(), 0);
2202     m_errorMonitor->VerifyFound();
2203 // Set this (for now, until all platforms are supported and tested):
2204 #define NEED_TO_TEST_THIS_ON_PLATFORM
2205 #endif // VK_USE_PLATFORM_WIN32_KHR
2206
2207 #if defined(VK_USE_PLATFORM_XCB_KHR)
2208     // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED
2209     // TO NON-LINUX PLATFORMS:
2210     VkSurfaceKHR surface = VK_NULL_HANDLE;
2211     // Use the functions from the VK_KHR_xcb_surface extension without enabling
2212     // that extension:
2213
2214     // Create a surface:
2215     VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
2216     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2217     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2218     pass = (err != VK_SUCCESS);
2219     ASSERT_TRUE(pass);
2220     m_errorMonitor->VerifyFound();
2221
2222     // Tell whether an xcb_visualid_t supports presentation:
2223     xcb_connection_t *xcb_connection = NULL;
2224     xcb_visualid_t visual_id = 0;
2225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2226     vkGetPhysicalDeviceXcbPresentationSupportKHR(gpu(), 0, xcb_connection, visual_id);
2227     m_errorMonitor->VerifyFound();
2228 // Set this (for now, until all platforms are supported and tested):
2229 #define NEED_TO_TEST_THIS_ON_PLATFORM
2230 #endif // VK_USE_PLATFORM_XCB_KHR
2231
2232 #if defined(VK_USE_PLATFORM_XLIB_KHR)
2233     // Use the functions from the VK_KHR_xlib_surface extension without enabling
2234     // that extension:
2235
2236     // Create a surface:
2237     VkXlibSurfaceCreateInfoKHR xlib_create_info = {};
2238     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2239     err = vkCreateXlibSurfaceKHR(instance(), &xlib_create_info, NULL, &surface);
2240     pass = (err != VK_SUCCESS);
2241     ASSERT_TRUE(pass);
2242     m_errorMonitor->VerifyFound();
2243
2244     // Tell whether an Xlib VisualID supports presentation:
2245     Display *dpy = NULL;
2246     VisualID visual = 0;
2247     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2248     vkGetPhysicalDeviceXlibPresentationSupportKHR(gpu(), 0, dpy, visual);
2249     m_errorMonitor->VerifyFound();
2250 // Set this (for now, until all platforms are supported and tested):
2251 #define NEED_TO_TEST_THIS_ON_PLATFORM
2252 #endif // VK_USE_PLATFORM_XLIB_KHR
2253
2254 // Use the functions from the VK_KHR_surface extension without enabling
2255 // that extension:
2256
2257 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
2258     // Destroy a surface:
2259     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2260     vkDestroySurfaceKHR(instance(), surface, NULL);
2261     m_errorMonitor->VerifyFound();
2262
2263     // Check if surface supports presentation:
2264     VkBool32 supported = false;
2265     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2266     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2267     pass = (err != VK_SUCCESS);
2268     ASSERT_TRUE(pass);
2269     m_errorMonitor->VerifyFound();
2270
2271     // Check surface capabilities:
2272     VkSurfaceCapabilitiesKHR capabilities = {};
2273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2274     err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &capabilities);
2275     pass = (err != VK_SUCCESS);
2276     ASSERT_TRUE(pass);
2277     m_errorMonitor->VerifyFound();
2278
2279     // Check surface formats:
2280     uint32_t format_count = 0;
2281     VkSurfaceFormatKHR *formats = NULL;
2282     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2283     err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &format_count, formats);
2284     pass = (err != VK_SUCCESS);
2285     ASSERT_TRUE(pass);
2286     m_errorMonitor->VerifyFound();
2287
2288     // Check surface present modes:
2289     uint32_t present_mode_count = 0;
2290     VkSurfaceFormatKHR *present_modes = NULL;
2291     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2292     err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &present_mode_count, present_modes);
2293     pass = (err != VK_SUCCESS);
2294     ASSERT_TRUE(pass);
2295     m_errorMonitor->VerifyFound();
2296 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
2297
2298     // Use the functions from the VK_KHR_swapchain extension without enabling
2299     // that extension:
2300
2301     // Create a swapchain:
2302     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2303     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2304     swapchain_create_info.pNext = NULL;
2305     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2306     pass = (err != VK_SUCCESS);
2307     ASSERT_TRUE(pass);
2308     m_errorMonitor->VerifyFound();
2309
2310     // Get the images from the swapchain:
2311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2312     err = vkGetSwapchainImagesKHR(m_device->device(), swapchain, &swapchain_image_count, NULL);
2313     pass = (err != VK_SUCCESS);
2314     ASSERT_TRUE(pass);
2315     m_errorMonitor->VerifyFound();
2316
2317     // Add a fence to avoid (justifiable) error about not providing fence OR semaphore
2318     VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2319     VkFence fence;
2320     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2321
2322     // Try to acquire an image:
2323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2324     err = vkAcquireNextImageKHR(m_device->device(), swapchain, 0, VK_NULL_HANDLE, fence, &image_index);
2325     pass = (err != VK_SUCCESS);
2326     ASSERT_TRUE(pass);
2327     m_errorMonitor->VerifyFound();
2328
2329     vkDestroyFence(m_device->device(), fence, nullptr);
2330
2331     // Try to present an image:
2332     //
2333     // NOTE: Currently can't test this because a real swapchain is needed (as
2334     // opposed to the fake one we created) in order for the layer to lookup the
2335     // VkDevice used to enable the extension:
2336
2337     // Destroy the swapchain:
2338     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2339     vkDestroySwapchainKHR(m_device->device(), swapchain, NULL);
2340     m_errorMonitor->VerifyFound();
2341 }
2342
2343 TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) {
2344
2345 #if defined(VK_USE_PLATFORM_XCB_KHR)
2346     VkSurfaceKHR surface = VK_NULL_HANDLE;
2347
2348     VkResult err;
2349     bool pass;
2350     VkSwapchainKHR swapchain = VK_NULL_HANDLE;
2351     VkSwapchainCreateInfoKHR swapchain_create_info = {};
2352     //    uint32_t swapchain_image_count = 0;
2353     //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
2354     //    uint32_t image_index = 0;
2355     //    VkPresentInfoKHR present_info = {};
2356
2357     ASSERT_NO_FATAL_FAILURE(InitState());
2358
2359     // Use the create function from one of the VK_KHR_*_surface extension in
2360     // order to create a surface, testing all known errors in the process,
2361     // before successfully creating a surface:
2362     // First, try to create a surface without a VkXcbSurfaceCreateInfoKHR:
2363     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo specified as NULL");
2364     err = vkCreateXcbSurfaceKHR(instance(), NULL, NULL, &surface);
2365     pass = (err != VK_SUCCESS);
2366     ASSERT_TRUE(pass);
2367     m_errorMonitor->VerifyFound();
2368
2369     // Next, try to create a surface with the wrong
2370     // VkXcbSurfaceCreateInfoKHR::sType:
2371     VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
2372     xcb_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2373     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2374     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2375     pass = (err != VK_SUCCESS);
2376     ASSERT_TRUE(pass);
2377     m_errorMonitor->VerifyFound();
2378
2379     // Create a native window, and then correctly create a surface:
2380     xcb_connection_t *connection;
2381     xcb_screen_t *screen;
2382     xcb_window_t xcb_window;
2383     xcb_intern_atom_reply_t *atom_wm_delete_window;
2384
2385     const xcb_setup_t *setup;
2386     xcb_screen_iterator_t iter;
2387     int scr;
2388     uint32_t value_mask, value_list[32];
2389     int width = 1;
2390     int height = 1;
2391
2392     connection = xcb_connect(NULL, &scr);
2393     ASSERT_TRUE(connection != NULL);
2394     setup = xcb_get_setup(connection);
2395     iter = xcb_setup_roots_iterator(setup);
2396     while (scr-- > 0)
2397         xcb_screen_next(&iter);
2398     screen = iter.data;
2399
2400     xcb_window = xcb_generate_id(connection);
2401
2402     value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
2403     value_list[0] = screen->black_pixel;
2404     value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
2405
2406     xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0,
2407                       XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list);
2408
2409     /* Magic code that will send notification when window is destroyed */
2410     xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
2411     xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0);
2412
2413     xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
2414     atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
2415     xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom);
2416     free(reply);
2417
2418     xcb_map_window(connection, xcb_window);
2419
2420     // Force the x/y coordinates to 100,100 results are identical in consecutive
2421     // runs
2422     const uint32_t coords[] = {100, 100};
2423     xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
2424
2425     // Finally, try to correctly create a surface:
2426     xcb_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
2427     xcb_create_info.pNext = NULL;
2428     xcb_create_info.flags = 0;
2429     xcb_create_info.connection = connection;
2430     xcb_create_info.window = xcb_window;
2431     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2432     pass = (err == VK_SUCCESS);
2433     ASSERT_TRUE(pass);
2434
2435     // Check if surface supports presentation:
2436
2437     // 1st, do so without having queried the queue families:
2438     VkBool32 supported = false;
2439     // TODO: Get the following error to come out:
2440     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2441                                          "called before calling the vkGetPhysicalDeviceQueueFamilyProperties "
2442                                          "function");
2443     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2444     pass = (err != VK_SUCCESS);
2445     //    ASSERT_TRUE(pass);
2446     //    m_errorMonitor->VerifyFound();
2447
2448     // Next, query a queue family index that's too large:
2449     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2450     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 100000, surface, &supported);
2451     pass = (err != VK_SUCCESS);
2452     ASSERT_TRUE(pass);
2453     m_errorMonitor->VerifyFound();
2454
2455     // Finally, do so correctly:
2456     // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2457     // SUPPORTED
2458     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2459     pass = (err == VK_SUCCESS);
2460     ASSERT_TRUE(pass);
2461
2462     // Before proceeding, try to create a swapchain without having called
2463     // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
2464     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2465     swapchain_create_info.pNext = NULL;
2466     swapchain_create_info.flags = 0;
2467     swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2468     swapchain_create_info.surface = surface;
2469     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2470                                          "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
2471     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2472     pass = (err != VK_SUCCESS);
2473     ASSERT_TRUE(pass);
2474     m_errorMonitor->VerifyFound();
2475
2476     // Get the surface capabilities:
2477     VkSurfaceCapabilitiesKHR surface_capabilities;
2478
2479     // Do so correctly (only error logged by this entrypoint is if the
2480     // extension isn't enabled):
2481     err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
2482     pass = (err == VK_SUCCESS);
2483     ASSERT_TRUE(pass);
2484
2485     // Get the surface formats:
2486     uint32_t surface_format_count;
2487
2488     // First, try without a pointer to surface_format_count:
2489     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
2490                                                                         "specified as NULL");
2491     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
2492     pass = (err == VK_SUCCESS);
2493     ASSERT_TRUE(pass);
2494     m_errorMonitor->VerifyFound();
2495
2496     // Next, call with a non-NULL pSurfaceFormats, even though we haven't
2497     // correctly done a 1st try (to get the count):
2498     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2499     surface_format_count = 0;
2500     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
2501     pass = (err == VK_SUCCESS);
2502     ASSERT_TRUE(pass);
2503     m_errorMonitor->VerifyFound();
2504
2505     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2506     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2507     pass = (err == VK_SUCCESS);
2508     ASSERT_TRUE(pass);
2509
2510     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2511     VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
2512
2513     // Next, do a 2nd try with surface_format_count being set too high:
2514     surface_format_count += 5;
2515     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2516     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2517     pass = (err == VK_SUCCESS);
2518     ASSERT_TRUE(pass);
2519     m_errorMonitor->VerifyFound();
2520
2521     // Finally, do a correct 1st and 2nd try:
2522     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2523     pass = (err == VK_SUCCESS);
2524     ASSERT_TRUE(pass);
2525     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2526     pass = (err == VK_SUCCESS);
2527     ASSERT_TRUE(pass);
2528
2529     // Get the surface present modes:
2530     uint32_t surface_present_mode_count;
2531
2532     // First, try without a pointer to surface_format_count:
2533     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
2534                                                                         "specified as NULL");
2535
2536     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
2537     pass = (err == VK_SUCCESS);
2538     ASSERT_TRUE(pass);
2539     m_errorMonitor->VerifyFound();
2540
2541     // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
2542     // correctly done a 1st try (to get the count):
2543     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2544     surface_present_mode_count = 0;
2545     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
2546                                               (VkPresentModeKHR *)&surface_present_mode_count);
2547     pass = (err == VK_SUCCESS);
2548     ASSERT_TRUE(pass);
2549     m_errorMonitor->VerifyFound();
2550
2551     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2552     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2553     pass = (err == VK_SUCCESS);
2554     ASSERT_TRUE(pass);
2555
2556     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2557     VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
2558
2559     // Next, do a 2nd try with surface_format_count being set too high:
2560     surface_present_mode_count += 5;
2561     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2562     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2563     pass = (err == VK_SUCCESS);
2564     ASSERT_TRUE(pass);
2565     m_errorMonitor->VerifyFound();
2566
2567     // Finally, do a correct 1st and 2nd try:
2568     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2569     pass = (err == VK_SUCCESS);
2570     ASSERT_TRUE(pass);
2571     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2572     pass = (err == VK_SUCCESS);
2573     ASSERT_TRUE(pass);
2574
2575     // Create a swapchain:
2576
2577     // First, try without a pointer to swapchain_create_info:
2578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
2579                                                                         "specified as NULL");
2580
2581     err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
2582     pass = (err != VK_SUCCESS);
2583     ASSERT_TRUE(pass);
2584     m_errorMonitor->VerifyFound();
2585
2586     // Next, call with a non-NULL swapchain_create_info, that has the wrong
2587     // sType:
2588     swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2589     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2590
2591     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2592     pass = (err != VK_SUCCESS);
2593     ASSERT_TRUE(pass);
2594     m_errorMonitor->VerifyFound();
2595
2596     // Next, call with a NULL swapchain pointer:
2597     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2598     swapchain_create_info.pNext = NULL;
2599     swapchain_create_info.flags = 0;
2600     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
2601                                                                         "specified as NULL");
2602
2603     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
2604     pass = (err != VK_SUCCESS);
2605     ASSERT_TRUE(pass);
2606     m_errorMonitor->VerifyFound();
2607
2608     // TODO: Enhance swapchain layer so that
2609     // swapchain_create_info.queueFamilyIndexCount is checked against something?
2610
2611     // Next, call with a queue family index that's too large:
2612     uint32_t queueFamilyIndex[2] = {100000, 0};
2613     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2614     swapchain_create_info.queueFamilyIndexCount = 2;
2615     swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
2616     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2617     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2618     pass = (err != VK_SUCCESS);
2619     ASSERT_TRUE(pass);
2620     m_errorMonitor->VerifyFound();
2621
2622     // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
2623     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2624     swapchain_create_info.queueFamilyIndexCount = 1;
2625     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2626                                          "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
2627                                          "pCreateInfo->pQueueFamilyIndices).");
2628     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2629     pass = (err != VK_SUCCESS);
2630     ASSERT_TRUE(pass);
2631     m_errorMonitor->VerifyFound();
2632
2633     // Next, call with an invalid imageSharingMode:
2634     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
2635     swapchain_create_info.queueFamilyIndexCount = 1;
2636     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2637                                          "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
2638     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2639     pass = (err != VK_SUCCESS);
2640     ASSERT_TRUE(pass);
2641     m_errorMonitor->VerifyFound();
2642     // Fix for the future:
2643     // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2644     // SUPPORTED
2645     swapchain_create_info.queueFamilyIndexCount = 0;
2646     queueFamilyIndex[0] = 0;
2647     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
2648
2649     // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
2650     // Get the images from a swapchain:
2651     // Acquire an image from a swapchain:
2652     // Present an image to a swapchain:
2653     // Destroy the swapchain:
2654
2655     // TODOs:
2656     //
2657     // - Try destroying the device without first destroying the swapchain
2658     //
2659     // - Try destroying the device without first destroying the surface
2660     //
2661     // - Try destroying the surface without first destroying the swapchain
2662
2663     // Destroy the surface:
2664     vkDestroySurfaceKHR(instance(), surface, NULL);
2665
2666     // Tear down the window:
2667     xcb_destroy_window(connection, xcb_window);
2668     xcb_disconnect(connection);
2669
2670 #else  // VK_USE_PLATFORM_XCB_KHR
2671     return;
2672 #endif // VK_USE_PLATFORM_XCB_KHR
2673 }
2674
2675 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2676     VkResult err;
2677     bool pass;
2678
2679     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2680                                          "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2681
2682     ASSERT_NO_FATAL_FAILURE(InitState());
2683
2684     // Create an image, allocate memory, free it, and then try to bind it
2685     VkImage image;
2686     VkDeviceMemory mem;
2687     VkMemoryRequirements mem_reqs;
2688
2689     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2690     const int32_t tex_width = 32;
2691     const int32_t tex_height = 32;
2692
2693     VkImageCreateInfo image_create_info = {};
2694     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2695     image_create_info.pNext = NULL;
2696     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2697     image_create_info.format = tex_format;
2698     image_create_info.extent.width = tex_width;
2699     image_create_info.extent.height = tex_height;
2700     image_create_info.extent.depth = 1;
2701     image_create_info.mipLevels = 1;
2702     image_create_info.arrayLayers = 1;
2703     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2704     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2705     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2706     image_create_info.flags = 0;
2707     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2708
2709     VkMemoryAllocateInfo mem_alloc = {};
2710     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2711     mem_alloc.pNext = NULL;
2712     mem_alloc.allocationSize = 0;
2713
2714     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2715     ASSERT_VK_SUCCESS(err);
2716
2717     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2718
2719     mem_alloc.allocationSize = mem_reqs.size;
2720
2721     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2722     if (!pass) { // If we can't find any unmappable memory this test doesn't
2723                  // make sense
2724         vkDestroyImage(m_device->device(), image, NULL);
2725         return;
2726     }
2727
2728     // allocate memory
2729     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2730     ASSERT_VK_SUCCESS(err);
2731
2732     // Try to bind free memory that has been freed
2733     err = vkBindImageMemory(m_device->device(), image, mem, 0);
2734     ASSERT_VK_SUCCESS(err);
2735
2736     // Map memory as if to initialize the image
2737     void *mappedAddress = NULL;
2738     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2739
2740     m_errorMonitor->VerifyFound();
2741
2742     vkDestroyImage(m_device->device(), image, NULL);
2743     vkFreeMemory(m_device->device(), mem, NULL);
2744 }
2745
2746 TEST_F(VkLayerTest, RebindMemory) {
2747     VkResult err;
2748     bool pass;
2749
2750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2751
2752     ASSERT_NO_FATAL_FAILURE(InitState());
2753
2754     // Create an image, allocate memory, free it, and then try to bind it
2755     VkImage image;
2756     VkDeviceMemory mem1;
2757     VkDeviceMemory mem2;
2758     VkMemoryRequirements mem_reqs;
2759
2760     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2761     const int32_t tex_width = 32;
2762     const int32_t tex_height = 32;
2763
2764     VkImageCreateInfo image_create_info = {};
2765     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2766     image_create_info.pNext = NULL;
2767     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2768     image_create_info.format = tex_format;
2769     image_create_info.extent.width = tex_width;
2770     image_create_info.extent.height = tex_height;
2771     image_create_info.extent.depth = 1;
2772     image_create_info.mipLevels = 1;
2773     image_create_info.arrayLayers = 1;
2774     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2775     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2776     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2777     image_create_info.flags = 0;
2778
2779     VkMemoryAllocateInfo mem_alloc = {};
2780     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2781     mem_alloc.pNext = NULL;
2782     mem_alloc.allocationSize = 0;
2783     mem_alloc.memoryTypeIndex = 0;
2784
2785     // Introduce failure, do NOT set memProps to
2786     // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2787     mem_alloc.memoryTypeIndex = 1;
2788     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2789     ASSERT_VK_SUCCESS(err);
2790
2791     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2792
2793     mem_alloc.allocationSize = mem_reqs.size;
2794     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2795     ASSERT_TRUE(pass);
2796
2797     // allocate 2 memory objects
2798     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2799     ASSERT_VK_SUCCESS(err);
2800     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2801     ASSERT_VK_SUCCESS(err);
2802
2803     // Bind first memory object to Image object
2804     err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2805     ASSERT_VK_SUCCESS(err);
2806
2807     // Introduce validation failure, try to bind a different memory object to
2808     // the same image object
2809     err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2810
2811     m_errorMonitor->VerifyFound();
2812
2813     vkDestroyImage(m_device->device(), image, NULL);
2814     vkFreeMemory(m_device->device(), mem1, NULL);
2815     vkFreeMemory(m_device->device(), mem2, NULL);
2816 }
2817
2818 TEST_F(VkLayerTest, SubmitSignaledFence) {
2819     vk_testing::Fence testFence;
2820
2821     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state.  Fences "
2822                                                                         "must be reset before being submitted");
2823
2824     VkFenceCreateInfo fenceInfo = {};
2825     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2826     fenceInfo.pNext = NULL;
2827     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2828
2829     ASSERT_NO_FATAL_FAILURE(InitState());
2830     ASSERT_NO_FATAL_FAILURE(InitViewport());
2831     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2832
2833     BeginCommandBuffer();
2834     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
2835     EndCommandBuffer();
2836
2837     testFence.init(*m_device, fenceInfo);
2838
2839     VkSubmitInfo submit_info;
2840     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2841     submit_info.pNext = NULL;
2842     submit_info.waitSemaphoreCount = 0;
2843     submit_info.pWaitSemaphores = NULL;
2844     submit_info.pWaitDstStageMask = NULL;
2845     submit_info.commandBufferCount = 1;
2846     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2847     submit_info.signalSemaphoreCount = 0;
2848     submit_info.pSignalSemaphores = NULL;
2849
2850     vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2851     vkQueueWaitIdle(m_device->m_queue);
2852
2853     m_errorMonitor->VerifyFound();
2854 }
2855 // This is a positive test. We used to expect error in this case but spec now
2856 // allows it
2857 TEST_F(VkLayerTest, ResetUnsignaledFence) {
2858     m_errorMonitor->ExpectSuccess();
2859     vk_testing::Fence testFence;
2860     VkFenceCreateInfo fenceInfo = {};
2861     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2862     fenceInfo.pNext = NULL;
2863
2864     ASSERT_NO_FATAL_FAILURE(InitState());
2865     testFence.init(*m_device, fenceInfo);
2866     VkFence fences[1] = {testFence.handle()};
2867     VkResult result = vkResetFences(m_device->device(), 1, fences);
2868     ASSERT_VK_SUCCESS(result);
2869
2870     m_errorMonitor->VerifyNotFound();
2871 }
2872 #if 0 // A few devices have issues with this test so disabling for now
2873 TEST_F(VkLayerTest, LongFenceChain)
2874 {
2875     m_errorMonitor->ExpectSuccess();
2876
2877     ASSERT_NO_FATAL_FAILURE(InitState());
2878     VkResult err;
2879
2880     std::vector<VkFence> fences;
2881
2882     const int chainLength = 32768;
2883
2884     for (int i = 0; i < chainLength; i++) {
2885         VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2886         VkFence fence;
2887         err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2888         ASSERT_VK_SUCCESS(err);
2889
2890         fences.push_back(fence);
2891
2892         VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
2893             0, nullptr, 0, nullptr };
2894         err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2895         ASSERT_VK_SUCCESS(err);
2896
2897     }
2898
2899     // BOOM, stack overflow.
2900     vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
2901
2902     for (auto fence : fences)
2903         vkDestroyFence(m_device->device(), fence, nullptr);
2904
2905     m_errorMonitor->VerifyNotFound();
2906 }
2907 #endif
2908 TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
2909     m_errorMonitor->ExpectSuccess();
2910
2911     ASSERT_NO_FATAL_FAILURE(InitState());
2912     VkResult err;
2913
2914     // Record (empty!) command buffer that can be submitted multiple times
2915     // simultaneously.
2916     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2917                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
2918     m_commandBuffer->BeginCommandBuffer(&cbbi);
2919     m_commandBuffer->EndCommandBuffer();
2920
2921     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2922     VkFence fence;
2923     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2924     ASSERT_VK_SUCCESS(err);
2925
2926     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
2927     VkSemaphore s1, s2;
2928     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
2929     ASSERT_VK_SUCCESS(err);
2930     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
2931     ASSERT_VK_SUCCESS(err);
2932
2933     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
2934     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
2935     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2936     ASSERT_VK_SUCCESS(err);
2937
2938     // Submit CB again, signaling s2.
2939     si.pSignalSemaphores = &s2;
2940     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2941     ASSERT_VK_SUCCESS(err);
2942
2943     // Wait for fence.
2944     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
2945     ASSERT_VK_SUCCESS(err);
2946
2947     // CB is still in flight from second submission, but semaphore s1 is no
2948     // longer in flight. delete it.
2949     vkDestroySemaphore(m_device->device(), s1, nullptr);
2950
2951     m_errorMonitor->VerifyNotFound();
2952
2953     // Force device idle and clean up remaining objects
2954     vkDeviceWaitIdle(m_device->device());
2955     vkDestroySemaphore(m_device->device(), s2, nullptr);
2956     vkDestroyFence(m_device->device(), fence, nullptr);
2957 }
2958
2959 TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
2960     m_errorMonitor->ExpectSuccess();
2961
2962     ASSERT_NO_FATAL_FAILURE(InitState());
2963     VkResult err;
2964
2965     // A fence created signaled
2966     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
2967     VkFence f1;
2968     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
2969     ASSERT_VK_SUCCESS(err);
2970
2971     // A fence created not
2972     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2973     VkFence f2;
2974     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
2975     ASSERT_VK_SUCCESS(err);
2976
2977     // Submit the unsignaled fence
2978     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
2979     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
2980
2981     // Wait on both fences, with signaled first.
2982     VkFence fences[] = {f1, f2};
2983     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
2984
2985     // Should have both retired!
2986     vkDestroyFence(m_device->device(), f1, nullptr);
2987     vkDestroyFence(m_device->device(), f2, nullptr);
2988
2989     m_errorMonitor->VerifyNotFound();
2990 }
2991
2992 TEST_F(VkLayerTest, InvalidUsageBits) {
2993     TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
2994                      "Initialize buffer with wrong usage then perform copy expecting errors "
2995                      "from both the image and the buffer (2 calls)");
2996     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
2997
2998     ASSERT_NO_FATAL_FAILURE(InitState());
2999     VkImageObj image(m_device);
3000     // Initialize image with USAGE_TRANSIENT_ATTACHMENT
3001     image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3002     ASSERT_TRUE(image.initialized());
3003
3004     VkImageView dsv;
3005     VkImageViewCreateInfo dsvci = {};
3006     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3007     dsvci.image = image.handle();
3008     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3009     dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
3010     dsvci.subresourceRange.layerCount = 1;
3011     dsvci.subresourceRange.baseMipLevel = 0;
3012     dsvci.subresourceRange.levelCount = 1;
3013     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3014
3015     // Create a view with depth / stencil aspect for image with different usage
3016     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3017
3018     m_errorMonitor->VerifyFound();
3019
3020     // Initialize buffer with TRANSFER_DST usage
3021     vk_testing::Buffer buffer;
3022     VkMemoryPropertyFlags reqs = 0;
3023     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3024     VkBufferImageCopy region = {};
3025     region.bufferRowLength = 128;
3026     region.bufferImageHeight = 128;
3027     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3028     region.imageSubresource.layerCount = 1;
3029     region.imageExtent.height = 16;
3030     region.imageExtent.width = 16;
3031     region.imageExtent.depth = 1;
3032
3033     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
3034     // Buffer usage not set to TRANSFER_SRC and image usage not set to
3035     // TRANSFER_DST
3036     BeginCommandBuffer();
3037     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3038                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3039     m_errorMonitor->VerifyFound();
3040
3041     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3042     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3043                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3044     m_errorMonitor->VerifyFound();
3045 }
3046
3047 TEST_F(VkLayerTest, ValidUsage) {
3048     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
3049                      "doesn't generate validation errors");
3050
3051     ASSERT_NO_FATAL_FAILURE(InitState());
3052
3053     m_errorMonitor->ExpectSuccess();
3054     // Verify that we can create a view with usage INPUT_ATTACHMENT
3055     VkImageObj image(m_device);
3056     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3057     ASSERT_TRUE(image.initialized());
3058     VkImageView imageView;
3059     VkImageViewCreateInfo ivci = {};
3060     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3061     ivci.image = image.handle();
3062     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3063     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3064     ivci.subresourceRange.layerCount = 1;
3065     ivci.subresourceRange.baseMipLevel = 0;
3066     ivci.subresourceRange.levelCount = 1;
3067     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3068
3069     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3070     m_errorMonitor->VerifyNotFound();
3071     vkDestroyImageView(m_device->device(), imageView, NULL);
3072 }
3073 #endif // MEM_TRACKER_TESTS
3074
3075 #if OBJ_TRACKER_TESTS
3076
3077 TEST_F(VkLayerTest, LeakAnObject) {
3078     VkResult err;
3079
3080     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3081
3082     // Note that we have to create a new device since destroying the
3083     // framework's device causes Teardown() to fail and just calling Teardown
3084     // will destroy the errorMonitor.
3085
3086     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3087
3088     ASSERT_NO_FATAL_FAILURE(InitState());
3089
3090     const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
3091     std::vector<VkDeviceQueueCreateInfo> queue_info;
3092     queue_info.reserve(queue_props.size());
3093     std::vector<std::vector<float>> queue_priorities;
3094     for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
3095         VkDeviceQueueCreateInfo qi = {};
3096         qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3097         qi.pNext = NULL;
3098         qi.queueFamilyIndex = i;
3099         qi.queueCount = queue_props[i].queueCount;
3100         queue_priorities.emplace_back(qi.queueCount, 0.0f);
3101         qi.pQueuePriorities = queue_priorities[i].data();
3102         queue_info.push_back(qi);
3103     }
3104
3105     std::vector<const char *> device_extension_names;
3106
3107     // The sacrificial device object
3108     VkDevice testDevice;
3109     VkDeviceCreateInfo device_create_info = {};
3110     auto features = m_device->phy().features();
3111     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3112     device_create_info.pNext = NULL;
3113     device_create_info.queueCreateInfoCount = queue_info.size();
3114     device_create_info.pQueueCreateInfos = queue_info.data();
3115     device_create_info.enabledLayerCount = 0;
3116     device_create_info.ppEnabledLayerNames = NULL;
3117     device_create_info.pEnabledFeatures = &features;
3118     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3119     ASSERT_VK_SUCCESS(err);
3120
3121     VkFence fence;
3122     VkFenceCreateInfo fence_create_info = {};
3123     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3124     fence_create_info.pNext = NULL;
3125     fence_create_info.flags = 0;
3126     err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3127     ASSERT_VK_SUCCESS(err);
3128
3129     // Induce failure by not calling vkDestroyFence
3130     vkDestroyDevice(testDevice, NULL);
3131     m_errorMonitor->VerifyFound();
3132 }
3133
3134 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3135
3136     TEST_DESCRIPTION("Allocate command buffers from one command pool and "
3137                      "attempt to delete them from another.");
3138
3139     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3140
3141     ASSERT_NO_FATAL_FAILURE(InitState());
3142     VkCommandPool command_pool_one;
3143     VkCommandPool command_pool_two;
3144
3145     VkCommandPoolCreateInfo pool_create_info{};
3146     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3147     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3148     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3149
3150     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3151
3152     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3153
3154     VkCommandBuffer command_buffer[9];
3155     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3156     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3157     command_buffer_allocate_info.commandPool = command_pool_one;
3158     command_buffer_allocate_info.commandBufferCount = 9;
3159     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3160     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3161
3162     vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]);
3163
3164     m_errorMonitor->VerifyFound();
3165
3166     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3167     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3168 }
3169
3170 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3171     VkResult err;
3172
3173     TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and "
3174                      "attempt to delete them from another.");
3175
3176     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3177
3178     ASSERT_NO_FATAL_FAILURE(InitState());
3179     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3180
3181     VkDescriptorPoolSize ds_type_count = {};
3182     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3183     ds_type_count.descriptorCount = 1;
3184
3185     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3186     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3187     ds_pool_ci.pNext = NULL;
3188     ds_pool_ci.flags = 0;
3189     ds_pool_ci.maxSets = 1;
3190     ds_pool_ci.poolSizeCount = 1;
3191     ds_pool_ci.pPoolSizes = &ds_type_count;
3192
3193     VkDescriptorPool ds_pool_one;
3194     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
3195     ASSERT_VK_SUCCESS(err);
3196
3197     // Create a second descriptor pool
3198     VkDescriptorPool ds_pool_two;
3199     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two);
3200     ASSERT_VK_SUCCESS(err);
3201
3202     VkDescriptorSetLayoutBinding dsl_binding = {};
3203     dsl_binding.binding = 0;
3204     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3205     dsl_binding.descriptorCount = 1;
3206     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3207     dsl_binding.pImmutableSamplers = NULL;
3208
3209     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3210     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3211     ds_layout_ci.pNext = NULL;
3212     ds_layout_ci.bindingCount = 1;
3213     ds_layout_ci.pBindings = &dsl_binding;
3214
3215     VkDescriptorSetLayout ds_layout;
3216     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3217     ASSERT_VK_SUCCESS(err);
3218
3219     VkDescriptorSet descriptorSet;
3220     VkDescriptorSetAllocateInfo alloc_info = {};
3221     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3222     alloc_info.descriptorSetCount = 1;
3223     alloc_info.descriptorPool = ds_pool_one;
3224     alloc_info.pSetLayouts = &ds_layout;
3225     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3226     ASSERT_VK_SUCCESS(err);
3227
3228     err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet);
3229
3230     m_errorMonitor->VerifyFound();
3231
3232     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3233     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
3234     vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL);
3235 }
3236
3237 TEST_F(VkLayerTest, CreateUnknownObject) {
3238     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3239
3240     TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3241
3242     ASSERT_NO_FATAL_FAILURE(InitState());
3243
3244     // Pass bogus handle into GetImageMemoryRequirements
3245     VkMemoryRequirements mem_reqs;
3246     uint64_t fakeImageHandle = 0xCADECADE;
3247     VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3248
3249     vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3250
3251     m_errorMonitor->VerifyFound();
3252 }
3253
3254 TEST_F(VkLayerTest, PipelineNotBound) {
3255     VkResult err;
3256
3257     TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3258
3259     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object ");
3260
3261     ASSERT_NO_FATAL_FAILURE(InitState());
3262     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3263
3264     VkDescriptorPoolSize ds_type_count = {};
3265     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3266     ds_type_count.descriptorCount = 1;
3267
3268     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3269     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3270     ds_pool_ci.pNext = NULL;
3271     ds_pool_ci.maxSets = 1;
3272     ds_pool_ci.poolSizeCount = 1;
3273     ds_pool_ci.pPoolSizes = &ds_type_count;
3274
3275     VkDescriptorPool ds_pool;
3276     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
3277     ASSERT_VK_SUCCESS(err);
3278
3279     VkDescriptorSetLayoutBinding dsl_binding = {};
3280     dsl_binding.binding = 0;
3281     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3282     dsl_binding.descriptorCount = 1;
3283     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3284     dsl_binding.pImmutableSamplers = NULL;
3285
3286     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3287     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3288     ds_layout_ci.pNext = NULL;
3289     ds_layout_ci.bindingCount = 1;
3290     ds_layout_ci.pBindings = &dsl_binding;
3291
3292     VkDescriptorSetLayout ds_layout;
3293     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3294     ASSERT_VK_SUCCESS(err);
3295
3296     VkDescriptorSet descriptorSet;
3297     VkDescriptorSetAllocateInfo alloc_info = {};
3298     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3299     alloc_info.descriptorSetCount = 1;
3300     alloc_info.descriptorPool = ds_pool;
3301     alloc_info.pSetLayouts = &ds_layout;
3302     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3303     ASSERT_VK_SUCCESS(err);
3304
3305     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
3306     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3307     pipeline_layout_ci.pNext = NULL;
3308     pipeline_layout_ci.setLayoutCount = 1;
3309     pipeline_layout_ci.pSetLayouts = &ds_layout;
3310
3311     VkPipelineLayout pipeline_layout;
3312     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
3313     ASSERT_VK_SUCCESS(err);
3314
3315     VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3316
3317     BeginCommandBuffer();
3318     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3319
3320     m_errorMonitor->VerifyFound();
3321
3322     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
3323     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3324     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
3325 }
3326
3327 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3328     VkResult err;
3329
3330     TEST_DESCRIPTION("Test validation check for an invalid memory type index "
3331                      "during bind[Buffer|Image]Memory time");
3332
3333     ASSERT_NO_FATAL_FAILURE(InitState());
3334
3335     // Create an image, allocate memory, set a bad typeIndex and then try to
3336     // bind it
3337     VkImage image;
3338     VkDeviceMemory mem;
3339     VkMemoryRequirements mem_reqs;
3340     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3341     const int32_t tex_width = 32;
3342     const int32_t tex_height = 32;
3343
3344     VkImageCreateInfo image_create_info = {};
3345     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3346     image_create_info.pNext = NULL;
3347     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3348     image_create_info.format = tex_format;
3349     image_create_info.extent.width = tex_width;
3350     image_create_info.extent.height = tex_height;
3351     image_create_info.extent.depth = 1;
3352     image_create_info.mipLevels = 1;
3353     image_create_info.arrayLayers = 1;
3354     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3355     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3356     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3357     image_create_info.flags = 0;
3358
3359     VkMemoryAllocateInfo mem_alloc = {};
3360     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3361     mem_alloc.pNext = NULL;
3362     mem_alloc.allocationSize = 0;
3363     mem_alloc.memoryTypeIndex = 0;
3364
3365     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3366     ASSERT_VK_SUCCESS(err);
3367
3368     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3369     mem_alloc.allocationSize = mem_reqs.size;
3370
3371     // Introduce Failure, select invalid TypeIndex
3372     VkPhysicalDeviceMemoryProperties memory_info;
3373
3374     vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3375     unsigned int i;
3376     for (i = 0; i < memory_info.memoryTypeCount; i++) {
3377         if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3378             mem_alloc.memoryTypeIndex = i;
3379             break;
3380         }
3381     }
3382     if (i >= memory_info.memoryTypeCount) {
3383         printf("No invalid memory type index could be found; skipped.\n");
3384         vkDestroyImage(m_device->device(), image, NULL);
3385         return;
3386     }
3387
3388     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3389
3390     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3391     ASSERT_VK_SUCCESS(err);
3392
3393     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3394     (void)err;
3395
3396     m_errorMonitor->VerifyFound();
3397
3398     vkDestroyImage(m_device->device(), image, NULL);
3399     vkFreeMemory(m_device->device(), mem, NULL);
3400 }
3401
3402 TEST_F(VkLayerTest, BindInvalidMemory) {
3403     VkResult err;
3404     bool pass;
3405
3406     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object ");
3407
3408     ASSERT_NO_FATAL_FAILURE(InitState());
3409
3410     // Create an image, allocate memory, free it, and then try to bind it
3411     VkImage image;
3412     VkDeviceMemory mem;
3413     VkMemoryRequirements mem_reqs;
3414
3415     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3416     const int32_t tex_width = 32;
3417     const int32_t tex_height = 32;
3418
3419     VkImageCreateInfo image_create_info = {};
3420     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3421     image_create_info.pNext = NULL;
3422     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3423     image_create_info.format = tex_format;
3424     image_create_info.extent.width = tex_width;
3425     image_create_info.extent.height = tex_height;
3426     image_create_info.extent.depth = 1;
3427     image_create_info.mipLevels = 1;
3428     image_create_info.arrayLayers = 1;
3429     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3430     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3431     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3432     image_create_info.flags = 0;
3433
3434     VkMemoryAllocateInfo mem_alloc = {};
3435     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3436     mem_alloc.pNext = NULL;
3437     mem_alloc.allocationSize = 0;
3438     mem_alloc.memoryTypeIndex = 0;
3439
3440     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3441     ASSERT_VK_SUCCESS(err);
3442
3443     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3444
3445     mem_alloc.allocationSize = mem_reqs.size;
3446
3447     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3448     ASSERT_TRUE(pass);
3449
3450     // allocate memory
3451     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3452     ASSERT_VK_SUCCESS(err);
3453
3454     // Introduce validation failure, free memory before binding
3455     vkFreeMemory(m_device->device(), mem, NULL);
3456
3457     // Try to bind free memory that has been freed
3458     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3459     // This may very well return an error.
3460     (void)err;
3461
3462     m_errorMonitor->VerifyFound();
3463
3464     vkDestroyImage(m_device->device(), image, NULL);
3465 }
3466
3467 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3468     VkResult err;
3469     bool pass;
3470
3471     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3472
3473     ASSERT_NO_FATAL_FAILURE(InitState());
3474
3475     // Create an image object, allocate memory, destroy the object and then try
3476     // to bind it
3477     VkImage image;
3478     VkDeviceMemory mem;
3479     VkMemoryRequirements mem_reqs;
3480
3481     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3482     const int32_t tex_width = 32;
3483     const int32_t tex_height = 32;
3484
3485     VkImageCreateInfo image_create_info = {};
3486     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3487     image_create_info.pNext = NULL;
3488     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3489     image_create_info.format = tex_format;
3490     image_create_info.extent.width = tex_width;
3491     image_create_info.extent.height = tex_height;
3492     image_create_info.extent.depth = 1;
3493     image_create_info.mipLevels = 1;
3494     image_create_info.arrayLayers = 1;
3495     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3496     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3497     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3498     image_create_info.flags = 0;
3499
3500     VkMemoryAllocateInfo mem_alloc = {};
3501     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3502     mem_alloc.pNext = NULL;
3503     mem_alloc.allocationSize = 0;
3504     mem_alloc.memoryTypeIndex = 0;
3505
3506     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3507     ASSERT_VK_SUCCESS(err);
3508
3509     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3510
3511     mem_alloc.allocationSize = mem_reqs.size;
3512     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3513     ASSERT_TRUE(pass);
3514
3515     // Allocate memory
3516     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3517     ASSERT_VK_SUCCESS(err);
3518
3519     // Introduce validation failure, destroy Image object before binding
3520     vkDestroyImage(m_device->device(), image, NULL);
3521     ASSERT_VK_SUCCESS(err);
3522
3523     // Now Try to bind memory to this destroyed object
3524     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3525     // This may very well return an error.
3526     (void)err;
3527
3528     m_errorMonitor->VerifyFound();
3529
3530     vkFreeMemory(m_device->device(), mem, NULL);
3531 }
3532
3533 #endif // OBJ_TRACKER_TESTS
3534
3535 #if DRAW_STATE_TESTS
3536
3537 TEST_F(VkLayerTest, ImageSampleCounts) {
3538
3539     TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger "
3540                      "validation errors.");
3541     ASSERT_NO_FATAL_FAILURE(InitState());
3542
3543     VkMemoryPropertyFlags reqs = 0;
3544     VkImageCreateInfo image_create_info = {};
3545     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3546     image_create_info.pNext = NULL;
3547     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3548     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3549     image_create_info.extent.width = 256;
3550     image_create_info.extent.height = 256;
3551     image_create_info.extent.depth = 1;
3552     image_create_info.mipLevels = 1;
3553     image_create_info.arrayLayers = 1;
3554     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3555     image_create_info.flags = 0;
3556
3557     VkImageBlit blit_region = {};
3558     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3559     blit_region.srcSubresource.baseArrayLayer = 0;
3560     blit_region.srcSubresource.layerCount = 1;
3561     blit_region.srcSubresource.mipLevel = 0;
3562     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3563     blit_region.dstSubresource.baseArrayLayer = 0;
3564     blit_region.dstSubresource.layerCount = 1;
3565     blit_region.dstSubresource.mipLevel = 0;
3566
3567     // Create two images, the source with sampleCount = 2, and attempt to blit
3568     // between them
3569     {
3570         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3571         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3572         vk_testing::Image src_image;
3573         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3574         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3575         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3576         vk_testing::Image dst_image;
3577         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3578         m_commandBuffer->BeginCommandBuffer();
3579         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3580                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3581                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3582         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3583                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3584         m_errorMonitor->VerifyFound();
3585         m_commandBuffer->EndCommandBuffer();
3586     }
3587
3588     // Create two images, the dest with sampleCount = 4, and attempt to blit
3589     // between them
3590     {
3591         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3592         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3593         vk_testing::Image src_image;
3594         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3595         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3596         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3597         vk_testing::Image dst_image;
3598         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3599         m_commandBuffer->BeginCommandBuffer();
3600         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3601                                                                             "of VK_SAMPLE_COUNT_4_BIT but "
3602                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3603         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3604                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3605         m_errorMonitor->VerifyFound();
3606         m_commandBuffer->EndCommandBuffer();
3607     }
3608
3609     VkBufferImageCopy copy_region = {};
3610     copy_region.bufferRowLength = 128;
3611     copy_region.bufferImageHeight = 128;
3612     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3613     copy_region.imageSubresource.layerCount = 1;
3614     copy_region.imageExtent.height = 64;
3615     copy_region.imageExtent.width = 64;
3616     copy_region.imageExtent.depth = 1;
3617
3618     // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3619     // buffer to image
3620     {
3621         vk_testing::Buffer src_buffer;
3622         VkMemoryPropertyFlags reqs = 0;
3623         src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3624         image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
3625         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3626         vk_testing::Image dst_image;
3627         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3628         m_commandBuffer->BeginCommandBuffer();
3629         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3630                                                                             "of VK_SAMPLE_COUNT_8_BIT but "
3631                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3632         vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(),
3633                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
3634         m_errorMonitor->VerifyFound();
3635         m_commandBuffer->EndCommandBuffer();
3636     }
3637
3638     // Create dst buffer and src image with sampleCount = 2 and attempt to copy
3639     // image to buffer
3640     {
3641         vk_testing::Buffer dst_buffer;
3642         dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3643         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3644         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3645         vk_testing::Image src_image;
3646         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3647         m_commandBuffer->BeginCommandBuffer();
3648         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3649                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3650                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3651         vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3652                                dst_buffer.handle(), 1, &copy_region);
3653         m_errorMonitor->VerifyFound();
3654         m_commandBuffer->EndCommandBuffer();
3655     }
3656 }
3657
3658 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
3659     VkResult err;
3660     bool pass;
3661
3662     TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
3663     ASSERT_NO_FATAL_FAILURE(InitState());
3664
3665     // If w/d/h granularity is 1, test is not meaningful
3666     // TODO: When virtual device limits are available, create a set of limits for this test that
3667     // will always have a granularity of > 1 for w, h, and d
3668     auto index = m_device->graphics_queue_node_index_;
3669     auto queue_family_properties = m_device->phy().queue_properties();
3670
3671     if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
3672         (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
3673         (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
3674         return;
3675     }
3676
3677     // Create two images of different types and try to copy between them
3678     VkImage srcImage;
3679     VkImage dstImage;
3680     VkDeviceMemory srcMem;
3681     VkDeviceMemory destMem;
3682     VkMemoryRequirements memReqs;
3683
3684     VkImageCreateInfo image_create_info = {};
3685     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3686     image_create_info.pNext = NULL;
3687     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3688     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3689     image_create_info.extent.width = 32;
3690     image_create_info.extent.height = 32;
3691     image_create_info.extent.depth = 1;
3692     image_create_info.mipLevels = 1;
3693     image_create_info.arrayLayers = 4;
3694     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3695     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3696     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3697     image_create_info.flags = 0;
3698
3699     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
3700     ASSERT_VK_SUCCESS(err);
3701
3702     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
3703     ASSERT_VK_SUCCESS(err);
3704
3705     // Allocate memory
3706     VkMemoryAllocateInfo memAlloc = {};
3707     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3708     memAlloc.pNext = NULL;
3709     memAlloc.allocationSize = 0;
3710     memAlloc.memoryTypeIndex = 0;
3711
3712     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
3713     memAlloc.allocationSize = memReqs.size;
3714     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3715     ASSERT_TRUE(pass);
3716     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
3717     ASSERT_VK_SUCCESS(err);
3718
3719     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
3720     memAlloc.allocationSize = memReqs.size;
3721     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3722     ASSERT_VK_SUCCESS(err);
3723     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
3724     ASSERT_VK_SUCCESS(err);
3725
3726     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
3727     ASSERT_VK_SUCCESS(err);
3728     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
3729     ASSERT_VK_SUCCESS(err);
3730
3731     BeginCommandBuffer();
3732     VkImageCopy copyRegion;
3733     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3734     copyRegion.srcSubresource.mipLevel = 0;
3735     copyRegion.srcSubresource.baseArrayLayer = 0;
3736     copyRegion.srcSubresource.layerCount = 1;
3737     copyRegion.srcOffset.x = 0;
3738     copyRegion.srcOffset.y = 0;
3739     copyRegion.srcOffset.z = 0;
3740     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3741     copyRegion.dstSubresource.mipLevel = 0;
3742     copyRegion.dstSubresource.baseArrayLayer = 0;
3743     copyRegion.dstSubresource.layerCount = 1;
3744     copyRegion.dstOffset.x = 0;
3745     copyRegion.dstOffset.y = 0;
3746     copyRegion.dstOffset.z = 0;
3747     copyRegion.extent.width = 1;
3748     copyRegion.extent.height = 1;
3749     copyRegion.extent.depth = 1;
3750
3751     // Introduce failure by setting srcOffset to a bad granularity value
3752     copyRegion.srcOffset.y = 3;
3753     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3754     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3755     m_errorMonitor->VerifyFound();
3756
3757     // Introduce failure by setting extent to a bad granularity value
3758     copyRegion.srcOffset.y = 0;
3759     copyRegion.extent.width = 3;
3760     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3761     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3762     m_errorMonitor->VerifyFound();
3763
3764     // Now do some buffer/image copies
3765     vk_testing::Buffer buffer;
3766     VkMemoryPropertyFlags reqs = 0;
3767     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3768     VkBufferImageCopy region = {};
3769     region.bufferOffset = 0;
3770     region.bufferRowLength = 3;
3771     region.bufferImageHeight = 128;
3772     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3773     region.imageSubresource.layerCount = 1;
3774     region.imageExtent.height = 16;
3775     region.imageExtent.width = 16;
3776     region.imageExtent.depth = 1;
3777     region.imageOffset.x = 0;
3778     region.imageOffset.y = 0;
3779     region.imageOffset.z = 0;
3780
3781     // Introduce failure by setting bufferRowLength to a bad granularity value
3782     region.bufferRowLength = 3;
3783     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3784     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3785                            &region);
3786     m_errorMonitor->VerifyFound();
3787     region.bufferRowLength = 128;
3788
3789     // Introduce failure by setting bufferOffset to a bad granularity value
3790     region.bufferOffset = 3;
3791     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3792     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3793                            &region);
3794     m_errorMonitor->VerifyFound();
3795     region.bufferOffset = 0;
3796
3797     // Introduce failure by setting bufferImageHeight to a bad granularity value
3798     region.bufferImageHeight = 3;
3799     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3800     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3801                            &region);
3802     m_errorMonitor->VerifyFound();
3803     region.bufferImageHeight = 128;
3804
3805     // Introduce failure by setting imageExtent to a bad granularity value
3806     region.imageExtent.width = 3;
3807     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3808     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3809                            &region);
3810     m_errorMonitor->VerifyFound();
3811     region.imageExtent.width = 16;
3812
3813     // Introduce failure by setting imageOffset to a bad granularity value
3814     region.imageOffset.z = 3;
3815     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3816     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3817                            &region);
3818     m_errorMonitor->VerifyFound();
3819
3820     EndCommandBuffer();
3821
3822     vkDestroyImage(m_device->device(), srcImage, NULL);
3823     vkDestroyImage(m_device->device(), dstImage, NULL);
3824     vkFreeMemory(m_device->device(), srcMem, NULL);
3825     vkFreeMemory(m_device->device(), destMem, NULL);
3826 }
3827
3828 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
3829     TEST_DESCRIPTION("Submit command buffer created using one queue family and "
3830                      "attempt to submit them on a queue created in a different "
3831                      "queue family.");
3832
3833     ASSERT_NO_FATAL_FAILURE(InitState());
3834     // This test is meaningless unless we have multiple queue families
3835     auto queue_family_properties = m_device->phy().queue_properties();
3836     if (queue_family_properties.size() < 2) {
3837         return;
3838     }
3839     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue ");
3840     // Get safe index of another queue family
3841     uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
3842     ASSERT_NO_FATAL_FAILURE(InitState());
3843     // Create a second queue using a different queue family
3844     VkQueue other_queue;
3845     vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
3846
3847     // Record an empty cmd buffer
3848     VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3849     cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3850     vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
3851     vkEndCommandBuffer(m_commandBuffer->handle());
3852
3853     // And submit on the wrong queue
3854     VkSubmitInfo submit_info = {};
3855     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3856     submit_info.commandBufferCount = 1;
3857     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3858     vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
3859
3860     m_errorMonitor->VerifyFound();
3861 }
3862
3863 TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
3864     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
3865                      "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
3866                      "the command buffer has prior knowledge of that "
3867                      "attachment's layout.");
3868
3869     m_errorMonitor->ExpectSuccess();
3870
3871     ASSERT_NO_FATAL_FAILURE(InitState());
3872
3873     // A renderpass with one color attachment.
3874     VkAttachmentDescription attachment = {0,
3875                                           VK_FORMAT_R8G8B8A8_UNORM,
3876                                           VK_SAMPLE_COUNT_1_BIT,
3877                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3878                                           VK_ATTACHMENT_STORE_OP_STORE,
3879                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3880                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3881                                           VK_IMAGE_LAYOUT_UNDEFINED,
3882                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3883
3884     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3885
3886     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3887
3888     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3889
3890     VkRenderPass rp;
3891     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3892     ASSERT_VK_SUCCESS(err);
3893
3894     // A compatible framebuffer.
3895     VkImageObj image(m_device);
3896     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3897     ASSERT_TRUE(image.initialized());
3898
3899     VkImageViewCreateInfo ivci = {
3900         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3901         nullptr,
3902         0,
3903         image.handle(),
3904         VK_IMAGE_VIEW_TYPE_2D,
3905         VK_FORMAT_R8G8B8A8_UNORM,
3906         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3907          VK_COMPONENT_SWIZZLE_IDENTITY},
3908         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3909     };
3910     VkImageView view;
3911     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3912     ASSERT_VK_SUCCESS(err);
3913
3914     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3915     VkFramebuffer fb;
3916     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3917     ASSERT_VK_SUCCESS(err);
3918
3919     // Record a single command buffer which uses this renderpass twice. The
3920     // bug is triggered at the beginning of the second renderpass, when the
3921     // command buffer already has a layout recorded for the attachment.
3922     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3923     BeginCommandBuffer();
3924     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3925     vkCmdEndRenderPass(m_commandBuffer->handle());
3926     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3927
3928     m_errorMonitor->VerifyNotFound();
3929
3930     vkCmdEndRenderPass(m_commandBuffer->handle());
3931     EndCommandBuffer();
3932
3933     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3934     vkDestroyRenderPass(m_device->device(), rp, nullptr);
3935     vkDestroyImageView(m_device->device(), view, nullptr);
3936 }
3937
3938 TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
3939     TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
3940                      "command buffer, bind them together, then destroy "
3941                      "command pool and framebuffer and verify there are no "
3942                      "errors.");
3943
3944     m_errorMonitor->ExpectSuccess();
3945
3946     ASSERT_NO_FATAL_FAILURE(InitState());
3947
3948     // A renderpass with one color attachment.
3949     VkAttachmentDescription attachment = {0,
3950                                           VK_FORMAT_R8G8B8A8_UNORM,
3951                                           VK_SAMPLE_COUNT_1_BIT,
3952                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3953                                           VK_ATTACHMENT_STORE_OP_STORE,
3954                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3955                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3956                                           VK_IMAGE_LAYOUT_UNDEFINED,
3957                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3958
3959     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3960
3961     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3962
3963     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3964
3965     VkRenderPass rp;
3966     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3967     ASSERT_VK_SUCCESS(err);
3968
3969     // A compatible framebuffer.
3970     VkImageObj image(m_device);
3971     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3972     ASSERT_TRUE(image.initialized());
3973
3974     VkImageViewCreateInfo ivci = {
3975         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3976         nullptr,
3977         0,
3978         image.handle(),
3979         VK_IMAGE_VIEW_TYPE_2D,
3980         VK_FORMAT_R8G8B8A8_UNORM,
3981         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3982          VK_COMPONENT_SWIZZLE_IDENTITY},
3983         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3984     };
3985     VkImageView view;
3986     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3987     ASSERT_VK_SUCCESS(err);
3988
3989     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3990     VkFramebuffer fb;
3991     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3992     ASSERT_VK_SUCCESS(err);
3993
3994     // Explicitly create a command buffer to bind the FB to so that we can then
3995     //  destroy the command pool in order to implicitly free command buffer
3996     VkCommandPool command_pool;
3997     VkCommandPoolCreateInfo pool_create_info{};
3998     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3999     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4000     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4001     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4002
4003     VkCommandBuffer command_buffer;
4004     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4005     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4006     command_buffer_allocate_info.commandPool = command_pool;
4007     command_buffer_allocate_info.commandBufferCount = 1;
4008     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4009     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4010
4011     // Begin our cmd buffer with renderpass using our framebuffer
4012     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4013     VkCommandBufferBeginInfo begin_info{};
4014     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4015     vkBeginCommandBuffer(command_buffer, &begin_info);
4016
4017     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4018     vkCmdEndRenderPass(command_buffer);
4019     vkEndCommandBuffer(command_buffer);
4020     vkDestroyImageView(m_device->device(), view, nullptr);
4021     // Destroy command pool to implicitly free command buffer
4022     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4023     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4024     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4025     m_errorMonitor->VerifyNotFound();
4026 }
4027
4028 TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
4029     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
4030                      "transitions for the first subpass");
4031
4032     m_errorMonitor->ExpectSuccess();
4033
4034     ASSERT_NO_FATAL_FAILURE(InitState());
4035
4036     // A renderpass with one color attachment.
4037     VkAttachmentDescription attachment = {0,
4038                                           VK_FORMAT_R8G8B8A8_UNORM,
4039                                           VK_SAMPLE_COUNT_1_BIT,
4040                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4041                                           VK_ATTACHMENT_STORE_OP_STORE,
4042                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4043                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4044                                           VK_IMAGE_LAYOUT_UNDEFINED,
4045                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4046
4047     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4048
4049     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4050
4051     VkSubpassDependency dep = {0,
4052                                0,
4053                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4054                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4055                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4056                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4057                                VK_DEPENDENCY_BY_REGION_BIT};
4058
4059     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4060
4061     VkResult err;
4062     VkRenderPass rp;
4063     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4064     ASSERT_VK_SUCCESS(err);
4065
4066     // A compatible framebuffer.
4067     VkImageObj image(m_device);
4068     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4069     ASSERT_TRUE(image.initialized());
4070
4071     VkImageViewCreateInfo ivci = {
4072         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4073         nullptr,
4074         0,
4075         image.handle(),
4076         VK_IMAGE_VIEW_TYPE_2D,
4077         VK_FORMAT_R8G8B8A8_UNORM,
4078         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
4079          VK_COMPONENT_SWIZZLE_IDENTITY},
4080         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
4081     };
4082     VkImageView view;
4083     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4084     ASSERT_VK_SUCCESS(err);
4085
4086     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4087     VkFramebuffer fb;
4088     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4089     ASSERT_VK_SUCCESS(err);
4090
4091     // Record a single command buffer which issues a pipeline barrier w/
4092     // image memory barrier for the attachment. This detects the previously
4093     // missing tracking of the subpass layout by throwing a validation error
4094     // if it doesn't occur.
4095     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4096     BeginCommandBuffer();
4097     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4098
4099     VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4100                                 nullptr,
4101                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4102                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4103                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4104                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4105                                 VK_QUEUE_FAMILY_IGNORED,
4106                                 VK_QUEUE_FAMILY_IGNORED,
4107                                 image.handle(),
4108                                 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
4109     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4110                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4111                          &imb);
4112
4113     vkCmdEndRenderPass(m_commandBuffer->handle());
4114     m_errorMonitor->VerifyNotFound();
4115     EndCommandBuffer();
4116
4117     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4118     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4119     vkDestroyImageView(m_device->device(), view, nullptr);
4120 }
4121
4122 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
4123     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4124     ASSERT_NO_FATAL_FAILURE(InitState());
4125
4126     // A renderpass with two subpasses, both writing the same attachment.
4127     VkAttachmentDescription attach[] = {
4128         { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
4129             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4130             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4131             VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4132         },
4133     };
4134     VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
4135     VkSubpassDescription subpasses[] = {
4136         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4137             1, &ref, nullptr, nullptr, 0, nullptr },
4138         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4139             1, &ref, nullptr, nullptr, 0, nullptr },
4140     };
4141     VkSubpassDependency dep = {
4142         0, 1,
4143         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4144         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4145         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4146         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4147         VK_DEPENDENCY_BY_REGION_BIT
4148     };
4149     VkRenderPassCreateInfo rpci = {
4150         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
4151         0, 1, attach, 2, subpasses, 1, &dep
4152     };
4153     VkRenderPass rp;
4154     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4155     ASSERT_VK_SUCCESS(err);
4156
4157     VkImageObj image(m_device);
4158     image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
4159                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4160                          VK_IMAGE_TILING_OPTIMAL, 0);
4161     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4162
4163     VkFramebufferCreateInfo fbci = {
4164         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
4165         0, rp, 1, &imageView, 32, 32, 1
4166     };
4167     VkFramebuffer fb;
4168     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4169     ASSERT_VK_SUCCESS(err);
4170
4171     char const *vsSource =
4172         "#version 450\n"
4173         "void main() { gl_Position = vec4(1); }\n";
4174     char const *fsSource =
4175         "#version 450\n"
4176         "layout(location=0) out vec4 color;\n"
4177         "void main() { color = vec4(1); }\n";
4178
4179     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4180     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4181     VkPipelineObj pipe(m_device);
4182     pipe.AddColorAttachment();
4183     pipe.AddShader(&vs);
4184     pipe.AddShader(&fs);
4185     VkViewport view_port = {};
4186     m_viewports.push_back(view_port);
4187     pipe.SetViewport(m_viewports);
4188     VkRect2D rect = {};
4189     m_scissors.push_back(rect);
4190     pipe.SetScissor(m_scissors);
4191
4192     VkPipelineLayoutCreateInfo plci = {
4193         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
4194         0, 0, nullptr, 0, nullptr
4195     };
4196     VkPipelineLayout pl;
4197     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
4198     ASSERT_VK_SUCCESS(err);
4199     pipe.CreateVKPipeline(pl, rp);
4200
4201     BeginCommandBuffer();
4202
4203     VkRenderPassBeginInfo rpbi = {
4204         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
4205         rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
4206     };
4207
4208     // subtest 1: bind in the wrong subpass
4209     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4210     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4211     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4212                                          "built for subpass 0 but used in subpass 1");
4213     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4214     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4215     m_errorMonitor->VerifyFound();
4216
4217     vkCmdEndRenderPass(m_commandBuffer->handle());
4218
4219     // subtest 2: bind in correct subpass, then transition to next subpass
4220     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4221     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4222     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4223     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4224                                          "built for subpass 0 but used in subpass 1");
4225     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4226     m_errorMonitor->VerifyFound();
4227
4228     vkCmdEndRenderPass(m_commandBuffer->handle());
4229
4230     EndCommandBuffer();
4231
4232     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
4233     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4234     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4235 }
4236
4237 TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
4238     TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
4239                      "is used as a depth/stencil framebuffer attachment, the "
4240                      "aspectMask is ignored and both depth and stencil image "
4241                      "subresources are used.");
4242
4243     VkFormatProperties format_properties;
4244     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
4245     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
4246         return;
4247     }
4248
4249     m_errorMonitor->ExpectSuccess();
4250
4251     ASSERT_NO_FATAL_FAILURE(InitState());
4252
4253     VkAttachmentDescription attachment = {0,
4254                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
4255                                           VK_SAMPLE_COUNT_1_BIT,
4256                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4257                                           VK_ATTACHMENT_STORE_OP_STORE,
4258                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4259                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4260                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4261                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4262
4263     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4264
4265     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
4266
4267     VkSubpassDependency dep = {0,
4268                                0,
4269                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4270                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4271                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4272                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4273                                VK_DEPENDENCY_BY_REGION_BIT};
4274
4275     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4276
4277     VkResult err;
4278     VkRenderPass rp;
4279     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4280     ASSERT_VK_SUCCESS(err);
4281
4282     VkImageObj image(m_device);
4283     image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
4284                          0x26, // usage
4285                          VK_IMAGE_TILING_OPTIMAL, 0);
4286     ASSERT_TRUE(image.initialized());
4287     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
4288
4289     VkImageViewCreateInfo ivci = {
4290         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4291         nullptr,
4292         0,
4293         image.handle(),
4294         VK_IMAGE_VIEW_TYPE_2D,
4295         VK_FORMAT_D32_SFLOAT_S8_UINT,
4296         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
4297         {0x2, 0, 1, 0, 1},
4298     };
4299     VkImageView view;
4300     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4301     ASSERT_VK_SUCCESS(err);
4302
4303     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4304     VkFramebuffer fb;
4305     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4306     ASSERT_VK_SUCCESS(err);
4307
4308     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4309     BeginCommandBuffer();
4310     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4311
4312     VkImageMemoryBarrier imb = {};
4313     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4314     imb.pNext = nullptr;
4315     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4316     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4317     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4318     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4319     imb.srcQueueFamilyIndex = 0;
4320     imb.dstQueueFamilyIndex = 0;
4321     imb.image = image.handle();
4322     imb.subresourceRange.aspectMask = 0x6;
4323     imb.subresourceRange.baseMipLevel = 0;
4324     imb.subresourceRange.levelCount = 0x1;
4325     imb.subresourceRange.baseArrayLayer = 0;
4326     imb.subresourceRange.layerCount = 0x1;
4327
4328     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4329                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4330                          &imb);
4331
4332     vkCmdEndRenderPass(m_commandBuffer->handle());
4333     EndCommandBuffer();
4334     QueueCommandBuffer(false);
4335     m_errorMonitor->VerifyNotFound();
4336
4337     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4338     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4339     vkDestroyImageView(m_device->device(), view, nullptr);
4340 }
4341
4342 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
4343     TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass"
4344                      "with extent outside of framebuffer");
4345     ASSERT_NO_FATAL_FAILURE(InitState());
4346     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4347
4348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea "
4349                                                                         "not within the bound of the framebuffer.");
4350
4351     // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
4352     m_renderPassBeginInfo.renderArea.extent.width = 257;
4353     m_renderPassBeginInfo.renderArea.extent.height = 257;
4354     BeginCommandBuffer();
4355     m_errorMonitor->VerifyFound();
4356 }
4357
4358 TEST_F(VkLayerTest, DisabledIndependentBlend) {
4359     TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent "
4360                      "blend and then specifying different blend states for two "
4361                      "attachements");
4362     VkPhysicalDeviceFeatures features = {};
4363     features.independentBlend = VK_FALSE;
4364     ASSERT_NO_FATAL_FAILURE(InitState(&features));
4365
4366     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4367                                          "Invalid Pipeline CreateInfo: If independent blend feature not "
4368                                          "enabled, all elements of pAttachments must be identical");
4369
4370     VkDescriptorSetObj descriptorSet(m_device);
4371     descriptorSet.AppendDummy();
4372     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4373
4374     VkPipelineObj pipeline(m_device);
4375     VkRenderpassObj renderpass(m_device);
4376     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4377     pipeline.AddShader(&vs);
4378
4379     VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
4380     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4381     att_state1.blendEnable = VK_TRUE;
4382     att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4383     att_state2.blendEnable = VK_FALSE;
4384     pipeline.AddColorAttachment(0, &att_state1);
4385     pipeline.AddColorAttachment(1, &att_state2);
4386     pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle());
4387     m_errorMonitor->VerifyFound();
4388 }
4389
4390 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) {
4391     TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify "
4392                      "depth attachments in subpass");
4393     ASSERT_NO_FATAL_FAILURE(InitState());
4394
4395     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4396                                          "vkCreateRenderPass has no depth/stencil attachment, yet subpass");
4397
4398     // Create a renderPass with a single color attachment
4399     VkAttachmentReference attach = {};
4400     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4401     VkSubpassDescription subpass = {};
4402     VkRenderPassCreateInfo rpci = {};
4403     rpci.subpassCount = 1;
4404     rpci.pSubpasses = &subpass;
4405     rpci.attachmentCount = 1;
4406     VkAttachmentDescription attach_desc = {};
4407     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4408     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4409     rpci.pAttachments = &attach_desc;
4410     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4411     VkRenderPass rp;
4412     subpass.pDepthStencilAttachment = &attach;
4413     subpass.pColorAttachments = NULL;
4414     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4415     m_errorMonitor->VerifyFound();
4416 }
4417
4418 TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
4419     TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
4420                      "errors, when an attachment reference is "
4421                      "VK_ATTACHMENT_UNUSED");
4422
4423     m_errorMonitor->ExpectSuccess();
4424
4425     ASSERT_NO_FATAL_FAILURE(InitState());
4426
4427     // A renderpass with no attachments
4428     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4429
4430     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4431
4432     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
4433
4434     VkRenderPass rp;
4435     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4436     ASSERT_VK_SUCCESS(err);
4437
4438     // A compatible framebuffer.
4439     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
4440     VkFramebuffer fb;
4441     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4442     ASSERT_VK_SUCCESS(err);
4443
4444     // Record a command buffer which just begins and ends the renderpass. The
4445     // bug manifests in BeginRenderPass.
4446     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4447     BeginCommandBuffer();
4448     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4449     vkCmdEndRenderPass(m_commandBuffer->handle());
4450     m_errorMonitor->VerifyNotFound();
4451     EndCommandBuffer();
4452
4453     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4454     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4455 }
4456
4457 // This is a positive test. No errors are expected.
4458 TEST_F(VkLayerTest, StencilLoadOp) {
4459     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
4460                      "CLEAR. stencil[Load|Store]Op used to be ignored.");
4461     VkResult result = VK_SUCCESS;
4462     VkImageFormatProperties formatProps;
4463     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
4464                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
4465                                              &formatProps);
4466     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
4467         return;
4468     }
4469
4470     ASSERT_NO_FATAL_FAILURE(InitState());
4471     VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
4472     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
4473                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4474     VkAttachmentDescription att = {};
4475     VkAttachmentReference ref = {};
4476     att.format = depth_stencil_fmt;
4477     att.samples = VK_SAMPLE_COUNT_1_BIT;
4478     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
4479     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
4480     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
4481     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
4482     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4483     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4484
4485     VkClearValue clear;
4486     clear.depthStencil.depth = 1.0;
4487     clear.depthStencil.stencil = 0;
4488     ref.attachment = 0;
4489     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4490
4491     VkSubpassDescription subpass = {};
4492     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4493     subpass.flags = 0;
4494     subpass.inputAttachmentCount = 0;
4495     subpass.pInputAttachments = NULL;
4496     subpass.colorAttachmentCount = 0;
4497     subpass.pColorAttachments = NULL;
4498     subpass.pResolveAttachments = NULL;
4499     subpass.pDepthStencilAttachment = &ref;
4500     subpass.preserveAttachmentCount = 0;
4501     subpass.pPreserveAttachments = NULL;
4502
4503     VkRenderPass rp;
4504     VkRenderPassCreateInfo rp_info = {};
4505     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4506     rp_info.attachmentCount = 1;
4507     rp_info.pAttachments = &att;
4508     rp_info.subpassCount = 1;
4509     rp_info.pSubpasses = &subpass;
4510     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
4511     ASSERT_VK_SUCCESS(result);
4512
4513     VkImageView *depthView = m_depthStencil->BindInfo();
4514     VkFramebufferCreateInfo fb_info = {};
4515     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4516     fb_info.pNext = NULL;
4517     fb_info.renderPass = rp;
4518     fb_info.attachmentCount = 1;
4519     fb_info.pAttachments = depthView;
4520     fb_info.width = 100;
4521     fb_info.height = 100;
4522     fb_info.layers = 1;
4523     VkFramebuffer fb;
4524     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4525     ASSERT_VK_SUCCESS(result);
4526
4527     VkRenderPassBeginInfo rpbinfo = {};
4528     rpbinfo.clearValueCount = 1;
4529     rpbinfo.pClearValues = &clear;
4530     rpbinfo.pNext = NULL;
4531     rpbinfo.renderPass = rp;
4532     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4533     rpbinfo.renderArea.extent.width = 100;
4534     rpbinfo.renderArea.extent.height = 100;
4535     rpbinfo.renderArea.offset.x = 0;
4536     rpbinfo.renderArea.offset.y = 0;
4537     rpbinfo.framebuffer = fb;
4538
4539     VkFence fence = {};
4540     VkFenceCreateInfo fence_ci = {};
4541     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4542     fence_ci.pNext = nullptr;
4543     fence_ci.flags = 0;
4544     result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
4545     ASSERT_VK_SUCCESS(result);
4546
4547     m_commandBuffer->BeginCommandBuffer();
4548     m_commandBuffer->BeginRenderPass(rpbinfo);
4549     m_commandBuffer->EndRenderPass();
4550     m_commandBuffer->EndCommandBuffer();
4551     m_commandBuffer->QueueCommandBuffer(fence);
4552
4553     VkImageObj destImage(m_device);
4554     destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4555                    VK_IMAGE_TILING_OPTIMAL, 0);
4556     VkImageMemoryBarrier barrier = {};
4557     VkImageSubresourceRange range;
4558     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4559     barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4560     barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4561     barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4562     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4563     barrier.image = m_depthStencil->handle();
4564     range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4565     range.baseMipLevel = 0;
4566     range.levelCount = 1;
4567     range.baseArrayLayer = 0;
4568     range.layerCount = 1;
4569     barrier.subresourceRange = range;
4570     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4571     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
4572     cmdbuf.BeginCommandBuffer();
4573     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4574                            &barrier);
4575     barrier.srcAccessMask = 0;
4576     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4577     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4578     barrier.image = destImage.handle();
4579     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4580     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4581                            &barrier);
4582     VkImageCopy cregion;
4583     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4584     cregion.srcSubresource.mipLevel = 0;
4585     cregion.srcSubresource.baseArrayLayer = 0;
4586     cregion.srcSubresource.layerCount = 1;
4587     cregion.srcOffset.x = 0;
4588     cregion.srcOffset.y = 0;
4589     cregion.srcOffset.z = 0;
4590     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4591     cregion.dstSubresource.mipLevel = 0;
4592     cregion.dstSubresource.baseArrayLayer = 0;
4593     cregion.dstSubresource.layerCount = 1;
4594     cregion.dstOffset.x = 0;
4595     cregion.dstOffset.y = 0;
4596     cregion.dstOffset.z = 0;
4597     cregion.extent.width = 100;
4598     cregion.extent.height = 100;
4599     cregion.extent.depth = 1;
4600     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
4601                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
4602     cmdbuf.EndCommandBuffer();
4603
4604     VkSubmitInfo submit_info;
4605     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4606     submit_info.pNext = NULL;
4607     submit_info.waitSemaphoreCount = 0;
4608     submit_info.pWaitSemaphores = NULL;
4609     submit_info.pWaitDstStageMask = NULL;
4610     submit_info.commandBufferCount = 1;
4611     submit_info.pCommandBuffers = &cmdbuf.handle();
4612     submit_info.signalSemaphoreCount = 0;
4613     submit_info.pSignalSemaphores = NULL;
4614
4615     m_errorMonitor->ExpectSuccess();
4616     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4617     m_errorMonitor->VerifyNotFound();
4618
4619     vkQueueWaitIdle(m_device->m_queue);
4620     vkDestroyFence(m_device->device(), fence, nullptr);
4621     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4622     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4623 }
4624
4625 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
4626     TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
4627                      "attachment reference of VK_ATTACHMENT_UNUSED");
4628
4629     ASSERT_NO_FATAL_FAILURE(InitState());
4630     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4631
4632     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED");
4633
4634     VkAttachmentReference color_attach = {};
4635     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4636     color_attach.attachment = 0;
4637     uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
4638     VkSubpassDescription subpass = {};
4639     subpass.colorAttachmentCount = 1;
4640     subpass.pColorAttachments = &color_attach;
4641     subpass.preserveAttachmentCount = 1;
4642     subpass.pPreserveAttachments = &preserve_attachment;
4643
4644     VkRenderPassCreateInfo rpci = {};
4645     rpci.subpassCount = 1;
4646     rpci.pSubpasses = &subpass;
4647     rpci.attachmentCount = 1;
4648     VkAttachmentDescription attach_desc = {};
4649     attach_desc.format = VK_FORMAT_UNDEFINED;
4650     rpci.pAttachments = &attach_desc;
4651     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4652     VkRenderPass rp;
4653     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4654
4655     m_errorMonitor->VerifyFound();
4656
4657     if (result == VK_SUCCESS) {
4658         vkDestroyRenderPass(m_device->device(), rp, NULL);
4659     }
4660 }
4661
4662 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
4663     TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
4664                      "when the source of a subpass multisample resolve "
4665                      "does not have multiple samples.");
4666
4667     ASSERT_NO_FATAL_FAILURE(InitState());
4668
4669     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4670                                          "Subpass 0 requests multisample resolve from attachment 0 which has "
4671                                          "VK_SAMPLE_COUNT_1_BIT");
4672
4673     VkAttachmentDescription attachments[] = {
4674         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4675          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4676          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4677         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4678          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4679          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4680     };
4681
4682     VkAttachmentReference color = {
4683         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4684     };
4685
4686     VkAttachmentReference resolve = {
4687         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4688     };
4689
4690     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4691
4692     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4693
4694     VkRenderPass rp;
4695     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4696
4697     m_errorMonitor->VerifyFound();
4698
4699     if (err == VK_SUCCESS)
4700         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4701 }
4702
4703 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
4704     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4705                      "when a subpass multisample resolve operation is "
4706                      "requested, and the destination of that resolve has "
4707                      "multiple samples.");
4708
4709     ASSERT_NO_FATAL_FAILURE(InitState());
4710
4711     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4712                                          "Subpass 0 requests multisample resolve into attachment 1, which "
4713                                          "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
4714
4715     VkAttachmentDescription attachments[] = {
4716         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4717          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4718          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4719         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4720          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4721          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4722     };
4723
4724     VkAttachmentReference color = {
4725         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4726     };
4727
4728     VkAttachmentReference resolve = {
4729         1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4730     };
4731
4732     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4733
4734     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4735
4736     VkRenderPass rp;
4737     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4738
4739     m_errorMonitor->VerifyFound();
4740
4741     if (err == VK_SUCCESS)
4742         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4743 }
4744
4745 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
4746     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4747                      "when the color and depth attachments used by a subpass "
4748                      "have inconsistent sample counts");
4749
4750     ASSERT_NO_FATAL_FAILURE(InitState());
4751
4752     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4753                                          "Subpass 0 attempts to render to attachments with inconsistent sample counts");
4754
4755     VkAttachmentDescription attachments[] = {
4756         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4757          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4758          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4759         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4760          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4761          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4762     };
4763
4764     VkAttachmentReference color[] = {
4765         {
4766             0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4767         },
4768         {
4769             1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4770         },
4771     };
4772
4773     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr};
4774
4775     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4776
4777     VkRenderPass rp;
4778     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4779
4780     m_errorMonitor->VerifyFound();
4781
4782     if (err == VK_SUCCESS)
4783         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4784 }
4785
4786 TEST_F(VkLayerTest, FramebufferCreateErrors) {
4787     TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
4788                      " 1. Mismatch between fb & renderPass attachmentCount\n"
4789                      " 2. Use a color image as depthStencil attachment\n"
4790                      " 3. Mismatch fb & renderPass attachment formats\n"
4791                      " 4. Mismatch fb & renderPass attachment #samples\n"
4792                      " 5. FB attachment w/ non-1 mip-levels\n"
4793                      " 6. FB attachment where dimensions don't match\n"
4794                      " 7. FB attachment w/o identity swizzle\n"
4795                      " 8. FB dimensions exceed physical device limits\n");
4796
4797     ASSERT_NO_FATAL_FAILURE(InitState());
4798     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4799
4800     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4801                                          "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
4802                                          "does not match attachmentCount of 1 of ");
4803
4804     // Create a renderPass with a single color attachment
4805     VkAttachmentReference attach = {};
4806     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4807     VkSubpassDescription subpass = {};
4808     subpass.pColorAttachments = &attach;
4809     VkRenderPassCreateInfo rpci = {};
4810     rpci.subpassCount = 1;
4811     rpci.pSubpasses = &subpass;
4812     rpci.attachmentCount = 1;
4813     VkAttachmentDescription attach_desc = {};
4814     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4815     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4816     rpci.pAttachments = &attach_desc;
4817     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4818     VkRenderPass rp;
4819     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4820     ASSERT_VK_SUCCESS(err);
4821
4822     VkImageView ivs[2];
4823     ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4824     ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4825     VkFramebufferCreateInfo fb_info = {};
4826     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4827     fb_info.pNext = NULL;
4828     fb_info.renderPass = rp;
4829     // Set mis-matching attachmentCount
4830     fb_info.attachmentCount = 2;
4831     fb_info.pAttachments = ivs;
4832     fb_info.width = 100;
4833     fb_info.height = 100;
4834     fb_info.layers = 1;
4835
4836     VkFramebuffer fb;
4837     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4838
4839     m_errorMonitor->VerifyFound();
4840     if (err == VK_SUCCESS) {
4841         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4842     }
4843     vkDestroyRenderPass(m_device->device(), rp, NULL);
4844
4845     // Create a renderPass with a depth-stencil attachment created with
4846     // IMAGE_USAGE_COLOR_ATTACHMENT
4847     // Add our color attachment to pDepthStencilAttachment
4848     subpass.pDepthStencilAttachment = &attach;
4849     subpass.pColorAttachments = NULL;
4850     VkRenderPass rp_ds;
4851     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
4852     ASSERT_VK_SUCCESS(err);
4853     // Set correct attachment count, but attachment has COLOR usage bit set
4854     fb_info.attachmentCount = 1;
4855     fb_info.renderPass = rp_ds;
4856
4857     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags ");
4858     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4859
4860     m_errorMonitor->VerifyFound();
4861     if (err == VK_SUCCESS) {
4862         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4863     }
4864     vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
4865
4866     // Create new renderpass with alternate attachment format from fb
4867     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
4868     subpass.pDepthStencilAttachment = NULL;
4869     subpass.pColorAttachments = &attach;
4870     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4871     ASSERT_VK_SUCCESS(err);
4872
4873     // Cause error due to mis-matched formats between rp & fb
4874     //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
4875     fb_info.renderPass = rp;
4876     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4877                                          " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
4878     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4879
4880     m_errorMonitor->VerifyFound();
4881     if (err == VK_SUCCESS) {
4882         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4883     }
4884     vkDestroyRenderPass(m_device->device(), rp, NULL);
4885
4886     // Create new renderpass with alternate sample count from fb
4887     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4888     attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
4889     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4890     ASSERT_VK_SUCCESS(err);
4891
4892     // Cause error due to mis-matched sample count between rp & fb
4893     fb_info.renderPass = rp;
4894     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples "
4895                                                                         "that do not match the "
4896                                                                         "VK_SAMPLE_COUNT_4_BIT ");
4897     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4898
4899     m_errorMonitor->VerifyFound();
4900     if (err == VK_SUCCESS) {
4901         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4902     }
4903
4904     vkDestroyRenderPass(m_device->device(), rp, NULL);
4905
4906     // Create a custom imageView with non-1 mip levels
4907     VkImageObj image(m_device);
4908     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4909     ASSERT_TRUE(image.initialized());
4910
4911     VkImageView view;
4912     VkImageViewCreateInfo ivci = {};
4913     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4914     ivci.image = image.handle();
4915     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4916     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4917     ivci.subresourceRange.layerCount = 1;
4918     ivci.subresourceRange.baseMipLevel = 0;
4919     // Set level count 2 (only 1 is allowed for FB attachment)
4920     ivci.subresourceRange.levelCount = 2;
4921     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4922     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4923     ASSERT_VK_SUCCESS(err);
4924     // Re-create renderpass to have matching sample count
4925     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4926     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4927     ASSERT_VK_SUCCESS(err);
4928
4929     fb_info.renderPass = rp;
4930     fb_info.pAttachments = &view;
4931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only ");
4932     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4933
4934     m_errorMonitor->VerifyFound();
4935     if (err == VK_SUCCESS) {
4936         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4937     }
4938     vkDestroyImageView(m_device->device(), view, NULL);
4939     // Update view to original color buffer and grow FB dimensions too big
4940     fb_info.pAttachments = ivs;
4941     fb_info.height = 1024;
4942     fb_info.width = 1024;
4943     fb_info.layers = 2;
4944     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at "
4945                                                                         "least as large. ");
4946     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4947
4948     m_errorMonitor->VerifyFound();
4949     if (err == VK_SUCCESS) {
4950         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4951     }
4952     // Create view attachment with non-identity swizzle
4953     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4954     ivci.image = image.handle();
4955     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4956     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4957     ivci.subresourceRange.layerCount = 1;
4958     ivci.subresourceRange.baseMipLevel = 0;
4959     ivci.subresourceRange.levelCount = 1;
4960     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4961     ivci.components.r = VK_COMPONENT_SWIZZLE_G;
4962     ivci.components.g = VK_COMPONENT_SWIZZLE_R;
4963     ivci.components.b = VK_COMPONENT_SWIZZLE_A;
4964     ivci.components.a = VK_COMPONENT_SWIZZLE_B;
4965     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4966     ASSERT_VK_SUCCESS(err);
4967
4968     fb_info.pAttachments = &view;
4969     fb_info.height = 100;
4970     fb_info.width = 100;
4971     fb_info.layers = 1;
4972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All "
4973                                                                         "framebuffer attachments must have "
4974                                                                         "been created with the identity "
4975                                                                         "swizzle. ");
4976     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4977
4978     m_errorMonitor->VerifyFound();
4979     if (err == VK_SUCCESS) {
4980         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4981     }
4982     vkDestroyImageView(m_device->device(), view, NULL);
4983     // Request fb that exceeds max dimensions
4984     // reset attachment to color attachment
4985     fb_info.pAttachments = ivs;
4986     fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
4987     fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
4988     fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
4989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo "
4990                                                                         "dimensions exceed physical device "
4991                                                                         "limits. ");
4992     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4993
4994     m_errorMonitor->VerifyFound();
4995     if (err == VK_SUCCESS) {
4996         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4997     }
4998
4999     vkDestroyRenderPass(m_device->device(), rp, NULL);
5000 }
5001
5002 // This is a positive test.  No errors should be generated.
5003 TEST_F(VkLayerTest, WaitEventThenSet) {
5004     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
5005
5006     m_errorMonitor->ExpectSuccess();
5007     ASSERT_NO_FATAL_FAILURE(InitState());
5008
5009     VkEvent event;
5010     VkEventCreateInfo event_create_info{};
5011     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5012     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5013
5014     VkCommandPool command_pool;
5015     VkCommandPoolCreateInfo pool_create_info{};
5016     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5017     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5018     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5019     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5020
5021     VkCommandBuffer command_buffer;
5022     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5023     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5024     command_buffer_allocate_info.commandPool = command_pool;
5025     command_buffer_allocate_info.commandBufferCount = 1;
5026     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5027     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5028
5029     VkQueue queue = VK_NULL_HANDLE;
5030     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5031
5032     {
5033         VkCommandBufferBeginInfo begin_info{};
5034         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5035         vkBeginCommandBuffer(command_buffer, &begin_info);
5036
5037         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
5038                         nullptr, 0, nullptr);
5039         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5040         vkEndCommandBuffer(command_buffer);
5041     }
5042     {
5043         VkSubmitInfo submit_info{};
5044         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5045         submit_info.commandBufferCount = 1;
5046         submit_info.pCommandBuffers = &command_buffer;
5047         submit_info.signalSemaphoreCount = 0;
5048         submit_info.pSignalSemaphores = nullptr;
5049         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5050     }
5051     { vkSetEvent(m_device->device(), event); }
5052
5053     vkQueueWaitIdle(queue);
5054
5055     vkDestroyEvent(m_device->device(), event, nullptr);
5056     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5057     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5058
5059     m_errorMonitor->VerifyNotFound();
5060 }
5061 // This is a positive test.  No errors should be generated.
5062 TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
5063     TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
5064
5065     ASSERT_NO_FATAL_FAILURE(InitState());
5066     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5067         return;
5068
5069     m_errorMonitor->ExpectSuccess();
5070
5071     VkQueryPool query_pool;
5072     VkQueryPoolCreateInfo query_pool_create_info{};
5073     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5074     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5075     query_pool_create_info.queryCount = 1;
5076     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5077
5078     VkCommandPool command_pool;
5079     VkCommandPoolCreateInfo pool_create_info{};
5080     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5081     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5082     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5083     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5084
5085     VkCommandBuffer command_buffer;
5086     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5087     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5088     command_buffer_allocate_info.commandPool = command_pool;
5089     command_buffer_allocate_info.commandBufferCount = 1;
5090     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5091     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5092
5093     VkCommandBuffer secondary_command_buffer;
5094     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5095     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
5096
5097     VkQueue queue = VK_NULL_HANDLE;
5098     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5099
5100     uint32_t qfi = 0;
5101     VkBufferCreateInfo buff_create_info = {};
5102     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5103     buff_create_info.size = 1024;
5104     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5105     buff_create_info.queueFamilyIndexCount = 1;
5106     buff_create_info.pQueueFamilyIndices = &qfi;
5107
5108     VkResult err;
5109     VkBuffer buffer;
5110     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5111     ASSERT_VK_SUCCESS(err);
5112     VkMemoryAllocateInfo mem_alloc = {};
5113     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5114     mem_alloc.pNext = NULL;
5115     mem_alloc.allocationSize = 1024;
5116     mem_alloc.memoryTypeIndex = 0;
5117
5118     VkMemoryRequirements memReqs;
5119     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5120     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5121     if (!pass) {
5122         vkDestroyBuffer(m_device->device(), buffer, NULL);
5123         return;
5124     }
5125
5126     VkDeviceMemory mem;
5127     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5128     ASSERT_VK_SUCCESS(err);
5129     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5130     ASSERT_VK_SUCCESS(err);
5131
5132     VkCommandBufferInheritanceInfo hinfo = {};
5133     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5134     hinfo.renderPass = VK_NULL_HANDLE;
5135     hinfo.subpass = 0;
5136     hinfo.framebuffer = VK_NULL_HANDLE;
5137     hinfo.occlusionQueryEnable = VK_FALSE;
5138     hinfo.queryFlags = 0;
5139     hinfo.pipelineStatistics = 0;
5140
5141     {
5142         VkCommandBufferBeginInfo begin_info{};
5143         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5144         begin_info.pInheritanceInfo = &hinfo;
5145         vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
5146
5147         vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
5148         vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5149
5150         vkEndCommandBuffer(secondary_command_buffer);
5151
5152         begin_info.pInheritanceInfo = nullptr;
5153         vkBeginCommandBuffer(command_buffer, &begin_info);
5154
5155         vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
5156         vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
5157
5158         vkEndCommandBuffer(command_buffer);
5159     }
5160     {
5161         VkSubmitInfo submit_info{};
5162         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5163         submit_info.commandBufferCount = 1;
5164         submit_info.pCommandBuffers = &command_buffer;
5165         submit_info.signalSemaphoreCount = 0;
5166         submit_info.pSignalSemaphores = nullptr;
5167         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5168     }
5169
5170     vkQueueWaitIdle(queue);
5171
5172     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5173     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5174     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
5175     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5176     vkDestroyBuffer(m_device->device(), buffer, NULL);
5177     vkFreeMemory(m_device->device(), mem, NULL);
5178
5179     m_errorMonitor->VerifyNotFound();
5180 }
5181
5182 // This is a positive test.  No errors should be generated.
5183 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
5184     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
5185
5186     ASSERT_NO_FATAL_FAILURE(InitState());
5187     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5188         return;
5189
5190     m_errorMonitor->ExpectSuccess();
5191
5192     VkQueryPool query_pool;
5193     VkQueryPoolCreateInfo query_pool_create_info{};
5194     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5195     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5196     query_pool_create_info.queryCount = 1;
5197     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5198
5199     VkCommandPool command_pool;
5200     VkCommandPoolCreateInfo pool_create_info{};
5201     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5202     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5203     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5204     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5205
5206     VkCommandBuffer command_buffer[2];
5207     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5208     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5209     command_buffer_allocate_info.commandPool = command_pool;
5210     command_buffer_allocate_info.commandBufferCount = 2;
5211     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5212     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5213
5214     VkQueue queue = VK_NULL_HANDLE;
5215     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5216
5217     uint32_t qfi = 0;
5218     VkBufferCreateInfo buff_create_info = {};
5219     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5220     buff_create_info.size = 1024;
5221     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5222     buff_create_info.queueFamilyIndexCount = 1;
5223     buff_create_info.pQueueFamilyIndices = &qfi;
5224
5225     VkResult err;
5226     VkBuffer buffer;
5227     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5228     ASSERT_VK_SUCCESS(err);
5229     VkMemoryAllocateInfo mem_alloc = {};
5230     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5231     mem_alloc.pNext = NULL;
5232     mem_alloc.allocationSize = 1024;
5233     mem_alloc.memoryTypeIndex = 0;
5234
5235     VkMemoryRequirements memReqs;
5236     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5237     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5238     if (!pass) {
5239         vkDestroyBuffer(m_device->device(), buffer, NULL);
5240         return;
5241     }
5242
5243     VkDeviceMemory mem;
5244     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5245     ASSERT_VK_SUCCESS(err);
5246     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5247     ASSERT_VK_SUCCESS(err);
5248
5249     {
5250         VkCommandBufferBeginInfo begin_info{};
5251         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5252         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5253
5254         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
5255         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5256
5257         vkEndCommandBuffer(command_buffer[0]);
5258
5259         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5260
5261         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
5262
5263         vkEndCommandBuffer(command_buffer[1]);
5264     }
5265     {
5266         VkSubmitInfo submit_info{};
5267         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5268         submit_info.commandBufferCount = 2;
5269         submit_info.pCommandBuffers = command_buffer;
5270         submit_info.signalSemaphoreCount = 0;
5271         submit_info.pSignalSemaphores = nullptr;
5272         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5273     }
5274
5275     vkQueueWaitIdle(queue);
5276
5277     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5278     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
5279     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5280     vkDestroyBuffer(m_device->device(), buffer, NULL);
5281     vkFreeMemory(m_device->device(), mem, NULL);
5282
5283     m_errorMonitor->VerifyNotFound();
5284 }
5285
5286 TEST_F(VkLayerTest, ResetEventThenSet) {
5287     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
5288
5289     m_errorMonitor->ExpectSuccess();
5290
5291     ASSERT_NO_FATAL_FAILURE(InitState());
5292     VkEvent event;
5293     VkEventCreateInfo event_create_info{};
5294     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5295     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5296
5297     VkCommandPool command_pool;
5298     VkCommandPoolCreateInfo pool_create_info{};
5299     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5300     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5301     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5302     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5303
5304     VkCommandBuffer command_buffer;
5305     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5306     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5307     command_buffer_allocate_info.commandPool = command_pool;
5308     command_buffer_allocate_info.commandBufferCount = 1;
5309     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5310     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5311
5312     VkQueue queue = VK_NULL_HANDLE;
5313     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5314
5315     {
5316         VkCommandBufferBeginInfo begin_info{};
5317         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5318         vkBeginCommandBuffer(command_buffer, &begin_info);
5319
5320         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5321         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
5322                         nullptr, 0, nullptr, 0, nullptr);
5323         vkEndCommandBuffer(command_buffer);
5324     }
5325     {
5326         VkSubmitInfo submit_info{};
5327         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5328         submit_info.commandBufferCount = 1;
5329         submit_info.pCommandBuffers = &command_buffer;
5330         submit_info.signalSemaphoreCount = 0;
5331         submit_info.pSignalSemaphores = nullptr;
5332         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5333     }
5334     {
5335         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
5336                                                                             "command buffer.");
5337         vkSetEvent(m_device->device(), event);
5338         m_errorMonitor->VerifyFound();
5339     }
5340
5341     vkQueueWaitIdle(queue);
5342
5343     vkDestroyEvent(m_device->device(), event, nullptr);
5344     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5345     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5346 }
5347
5348 // This is a positive test.  No errors should be generated.
5349 TEST_F(VkLayerTest, TwoFencesThreeFrames) {
5350     TEST_DESCRIPTION("Two command buffers with two separate fences are each "
5351                      "run through a Submit & WaitForFences cycle 3 times. This "
5352                      "previously revealed a bug so running this positive test "
5353                      "to prevent a regression.");
5354     m_errorMonitor->ExpectSuccess();
5355
5356     ASSERT_NO_FATAL_FAILURE(InitState());
5357     VkQueue queue = VK_NULL_HANDLE;
5358     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5359
5360     static const uint32_t NUM_OBJECTS = 2;
5361     static const uint32_t NUM_FRAMES = 3;
5362     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
5363     VkFence fences[NUM_OBJECTS] = {};
5364
5365     VkCommandPool cmd_pool;
5366     VkCommandPoolCreateInfo cmd_pool_ci = {};
5367     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5368     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
5369     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5370     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
5371     ASSERT_VK_SUCCESS(err);
5372
5373     VkCommandBufferAllocateInfo cmd_buf_info = {};
5374     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5375     cmd_buf_info.commandPool = cmd_pool;
5376     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5377     cmd_buf_info.commandBufferCount = 1;
5378
5379     VkFenceCreateInfo fence_ci = {};
5380     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5381     fence_ci.pNext = nullptr;
5382     fence_ci.flags = 0;
5383
5384     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5385         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
5386         ASSERT_VK_SUCCESS(err);
5387         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
5388         ASSERT_VK_SUCCESS(err);
5389     }
5390
5391     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
5392         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
5393             // Create empty cmd buffer
5394             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
5395             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5396
5397             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
5398             ASSERT_VK_SUCCESS(err);
5399             err = vkEndCommandBuffer(cmd_buffers[obj]);
5400             ASSERT_VK_SUCCESS(err);
5401
5402             VkSubmitInfo submit_info = {};
5403             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5404             submit_info.commandBufferCount = 1;
5405             submit_info.pCommandBuffers = &cmd_buffers[obj];
5406             // Submit cmd buffer and wait for fence
5407             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
5408             ASSERT_VK_SUCCESS(err);
5409             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
5410             ASSERT_VK_SUCCESS(err);
5411             err = vkResetFences(m_device->device(), 1, &fences[obj]);
5412             ASSERT_VK_SUCCESS(err);
5413         }
5414     }
5415     m_errorMonitor->VerifyNotFound();
5416     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
5417     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5418         vkDestroyFence(m_device->device(), fences[i], nullptr);
5419     }
5420 }
5421 // This is a positive test.  No errors should be generated.
5422 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
5423
5424     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5425                      "submitted on separate queues followed by a QueueWaitIdle.");
5426
5427     ASSERT_NO_FATAL_FAILURE(InitState());
5428     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5429         return;
5430
5431     m_errorMonitor->ExpectSuccess();
5432
5433     VkSemaphore semaphore;
5434     VkSemaphoreCreateInfo semaphore_create_info{};
5435     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5436     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5437
5438     VkCommandPool command_pool;
5439     VkCommandPoolCreateInfo pool_create_info{};
5440     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5441     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5442     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5443     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5444
5445     VkCommandBuffer command_buffer[2];
5446     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5447     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5448     command_buffer_allocate_info.commandPool = command_pool;
5449     command_buffer_allocate_info.commandBufferCount = 2;
5450     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5451     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5452
5453     VkQueue queue = VK_NULL_HANDLE;
5454     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5455
5456     {
5457         VkCommandBufferBeginInfo begin_info{};
5458         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5459         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5460
5461         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5462                              nullptr, 0, nullptr, 0, nullptr);
5463
5464         VkViewport viewport{};
5465         viewport.maxDepth = 1.0f;
5466         viewport.minDepth = 0.0f;
5467         viewport.width = 512;
5468         viewport.height = 512;
5469         viewport.x = 0;
5470         viewport.y = 0;
5471         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5472         vkEndCommandBuffer(command_buffer[0]);
5473     }
5474     {
5475         VkCommandBufferBeginInfo begin_info{};
5476         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5477         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5478
5479         VkViewport viewport{};
5480         viewport.maxDepth = 1.0f;
5481         viewport.minDepth = 0.0f;
5482         viewport.width = 512;
5483         viewport.height = 512;
5484         viewport.x = 0;
5485         viewport.y = 0;
5486         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5487         vkEndCommandBuffer(command_buffer[1]);
5488     }
5489     {
5490         VkSubmitInfo submit_info{};
5491         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5492         submit_info.commandBufferCount = 1;
5493         submit_info.pCommandBuffers = &command_buffer[0];
5494         submit_info.signalSemaphoreCount = 1;
5495         submit_info.pSignalSemaphores = &semaphore;
5496         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5497     }
5498     {
5499         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5500         VkSubmitInfo submit_info{};
5501         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5502         submit_info.commandBufferCount = 1;
5503         submit_info.pCommandBuffers = &command_buffer[1];
5504         submit_info.waitSemaphoreCount = 1;
5505         submit_info.pWaitSemaphores = &semaphore;
5506         submit_info.pWaitDstStageMask = flags;
5507         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5508     }
5509
5510     vkQueueWaitIdle(m_device->m_queue);
5511
5512     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5513     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5514     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5515
5516     m_errorMonitor->VerifyNotFound();
5517 }
5518
5519 // This is a positive test.  No errors should be generated.
5520 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
5521
5522     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5523                      "submitted on separate queues, the second having a fence"
5524                      "followed by a QueueWaitIdle.");
5525
5526     ASSERT_NO_FATAL_FAILURE(InitState());
5527     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5528         return;
5529
5530     m_errorMonitor->ExpectSuccess();
5531
5532     VkFence fence;
5533     VkFenceCreateInfo fence_create_info{};
5534     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5535     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5536
5537     VkSemaphore semaphore;
5538     VkSemaphoreCreateInfo semaphore_create_info{};
5539     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5540     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5541
5542     VkCommandPool command_pool;
5543     VkCommandPoolCreateInfo pool_create_info{};
5544     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5545     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5546     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5547     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5548
5549     VkCommandBuffer command_buffer[2];
5550     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5551     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5552     command_buffer_allocate_info.commandPool = command_pool;
5553     command_buffer_allocate_info.commandBufferCount = 2;
5554     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5555     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5556
5557     VkQueue queue = VK_NULL_HANDLE;
5558     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5559
5560     {
5561         VkCommandBufferBeginInfo begin_info{};
5562         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5563         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5564
5565         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5566                              nullptr, 0, nullptr, 0, nullptr);
5567
5568         VkViewport viewport{};
5569         viewport.maxDepth = 1.0f;
5570         viewport.minDepth = 0.0f;
5571         viewport.width = 512;
5572         viewport.height = 512;
5573         viewport.x = 0;
5574         viewport.y = 0;
5575         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5576         vkEndCommandBuffer(command_buffer[0]);
5577     }
5578     {
5579         VkCommandBufferBeginInfo begin_info{};
5580         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5581         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5582
5583         VkViewport viewport{};
5584         viewport.maxDepth = 1.0f;
5585         viewport.minDepth = 0.0f;
5586         viewport.width = 512;
5587         viewport.height = 512;
5588         viewport.x = 0;
5589         viewport.y = 0;
5590         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5591         vkEndCommandBuffer(command_buffer[1]);
5592     }
5593     {
5594         VkSubmitInfo submit_info{};
5595         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5596         submit_info.commandBufferCount = 1;
5597         submit_info.pCommandBuffers = &command_buffer[0];
5598         submit_info.signalSemaphoreCount = 1;
5599         submit_info.pSignalSemaphores = &semaphore;
5600         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5601     }
5602     {
5603         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5604         VkSubmitInfo submit_info{};
5605         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5606         submit_info.commandBufferCount = 1;
5607         submit_info.pCommandBuffers = &command_buffer[1];
5608         submit_info.waitSemaphoreCount = 1;
5609         submit_info.pWaitSemaphores = &semaphore;
5610         submit_info.pWaitDstStageMask = flags;
5611         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5612     }
5613
5614     vkQueueWaitIdle(m_device->m_queue);
5615
5616     vkDestroyFence(m_device->device(), fence, nullptr);
5617     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5618     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5619     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5620
5621     m_errorMonitor->VerifyNotFound();
5622 }
5623
5624 // This is a positive test.  No errors should be generated.
5625 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
5626
5627     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5628                      "submitted on separate queues, the second having a fence"
5629                      "followed by two consecutive WaitForFences calls on the same fence.");
5630
5631     ASSERT_NO_FATAL_FAILURE(InitState());
5632     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5633         return;
5634
5635     m_errorMonitor->ExpectSuccess();
5636
5637     VkFence fence;
5638     VkFenceCreateInfo fence_create_info{};
5639     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5640     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5641
5642     VkSemaphore semaphore;
5643     VkSemaphoreCreateInfo semaphore_create_info{};
5644     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5645     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5646
5647     VkCommandPool command_pool;
5648     VkCommandPoolCreateInfo pool_create_info{};
5649     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5650     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5651     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5652     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5653
5654     VkCommandBuffer command_buffer[2];
5655     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5656     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5657     command_buffer_allocate_info.commandPool = command_pool;
5658     command_buffer_allocate_info.commandBufferCount = 2;
5659     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5660     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5661
5662     VkQueue queue = VK_NULL_HANDLE;
5663     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5664
5665     {
5666         VkCommandBufferBeginInfo begin_info{};
5667         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5668         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5669
5670         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5671                              nullptr, 0, nullptr, 0, nullptr);
5672
5673         VkViewport viewport{};
5674         viewport.maxDepth = 1.0f;
5675         viewport.minDepth = 0.0f;
5676         viewport.width = 512;
5677         viewport.height = 512;
5678         viewport.x = 0;
5679         viewport.y = 0;
5680         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5681         vkEndCommandBuffer(command_buffer[0]);
5682     }
5683     {
5684         VkCommandBufferBeginInfo begin_info{};
5685         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5686         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5687
5688         VkViewport viewport{};
5689         viewport.maxDepth = 1.0f;
5690         viewport.minDepth = 0.0f;
5691         viewport.width = 512;
5692         viewport.height = 512;
5693         viewport.x = 0;
5694         viewport.y = 0;
5695         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5696         vkEndCommandBuffer(command_buffer[1]);
5697     }
5698     {
5699         VkSubmitInfo submit_info{};
5700         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5701         submit_info.commandBufferCount = 1;
5702         submit_info.pCommandBuffers = &command_buffer[0];
5703         submit_info.signalSemaphoreCount = 1;
5704         submit_info.pSignalSemaphores = &semaphore;
5705         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5706     }
5707     {
5708         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5709         VkSubmitInfo submit_info{};
5710         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5711         submit_info.commandBufferCount = 1;
5712         submit_info.pCommandBuffers = &command_buffer[1];
5713         submit_info.waitSemaphoreCount = 1;
5714         submit_info.pWaitSemaphores = &semaphore;
5715         submit_info.pWaitDstStageMask = flags;
5716         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5717     }
5718
5719     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5720     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5721
5722     vkDestroyFence(m_device->device(), fence, nullptr);
5723     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5724     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5725     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5726
5727     m_errorMonitor->VerifyNotFound();
5728 }
5729
5730 TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
5731
5732     ASSERT_NO_FATAL_FAILURE(InitState());
5733     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
5734         printf("Test requires two queues, skipping\n");
5735         return;
5736     }
5737
5738     VkResult err;
5739
5740     m_errorMonitor->ExpectSuccess();
5741
5742     VkQueue q0 = m_device->m_queue;
5743     VkQueue q1 = nullptr;
5744     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
5745     ASSERT_NE(q1, nullptr);
5746
5747     // An (empty) command buffer. We must have work in the first submission --
5748     // the layer treats unfenced work differently from fenced work.
5749     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
5750     VkCommandPool pool;
5751     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
5752     ASSERT_VK_SUCCESS(err);
5753     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
5754                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
5755     VkCommandBuffer cb;
5756     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
5757     ASSERT_VK_SUCCESS(err);
5758     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
5759     err = vkBeginCommandBuffer(cb, &cbbi);
5760     ASSERT_VK_SUCCESS(err);
5761     err = vkEndCommandBuffer(cb);
5762     ASSERT_VK_SUCCESS(err);
5763
5764     // A semaphore
5765     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5766     VkSemaphore s;
5767     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
5768     ASSERT_VK_SUCCESS(err);
5769
5770     // First submission, to q0
5771     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
5772
5773     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
5774     ASSERT_VK_SUCCESS(err);
5775
5776     // Second submission, to q1, waiting on s
5777     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
5778     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
5779
5780     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
5781     ASSERT_VK_SUCCESS(err);
5782
5783     // Wait for q0 idle
5784     err = vkQueueWaitIdle(q0);
5785     ASSERT_VK_SUCCESS(err);
5786
5787     // Command buffer should have been completed (it was on q0); reset the pool.
5788     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
5789
5790     m_errorMonitor->VerifyNotFound();
5791
5792     // Force device completely idle and clean up resources
5793     vkDeviceWaitIdle(m_device->device());
5794     vkDestroyCommandPool(m_device->device(), pool, nullptr);
5795     vkDestroySemaphore(m_device->device(), s, nullptr);
5796 }
5797
5798 // This is a positive test.  No errors should be generated.
5799 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
5800
5801     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5802                      "submitted on separate queues, the second having a fence, "
5803                      "followed by a WaitForFences call.");
5804
5805     ASSERT_NO_FATAL_FAILURE(InitState());
5806     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5807         return;
5808
5809     m_errorMonitor->ExpectSuccess();
5810
5811     ASSERT_NO_FATAL_FAILURE(InitState());
5812     VkFence fence;
5813     VkFenceCreateInfo fence_create_info{};
5814     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5815     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5816
5817     VkSemaphore semaphore;
5818     VkSemaphoreCreateInfo semaphore_create_info{};
5819     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5820     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5821
5822     VkCommandPool command_pool;
5823     VkCommandPoolCreateInfo pool_create_info{};
5824     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5825     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5826     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5827     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5828
5829     VkCommandBuffer command_buffer[2];
5830     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5831     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5832     command_buffer_allocate_info.commandPool = command_pool;
5833     command_buffer_allocate_info.commandBufferCount = 2;
5834     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5835     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5836
5837     VkQueue queue = VK_NULL_HANDLE;
5838     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5839
5840     {
5841         VkCommandBufferBeginInfo begin_info{};
5842         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5843         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5844
5845         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5846                              nullptr, 0, nullptr, 0, nullptr);
5847
5848         VkViewport viewport{};
5849         viewport.maxDepth = 1.0f;
5850         viewport.minDepth = 0.0f;
5851         viewport.width = 512;
5852         viewport.height = 512;
5853         viewport.x = 0;
5854         viewport.y = 0;
5855         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5856         vkEndCommandBuffer(command_buffer[0]);
5857     }
5858     {
5859         VkCommandBufferBeginInfo begin_info{};
5860         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5861         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5862
5863         VkViewport viewport{};
5864         viewport.maxDepth = 1.0f;
5865         viewport.minDepth = 0.0f;
5866         viewport.width = 512;
5867         viewport.height = 512;
5868         viewport.x = 0;
5869         viewport.y = 0;
5870         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5871         vkEndCommandBuffer(command_buffer[1]);
5872     }
5873     {
5874         VkSubmitInfo submit_info{};
5875         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5876         submit_info.commandBufferCount = 1;
5877         submit_info.pCommandBuffers = &command_buffer[0];
5878         submit_info.signalSemaphoreCount = 1;
5879         submit_info.pSignalSemaphores = &semaphore;
5880         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5881     }
5882     {
5883         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5884         VkSubmitInfo submit_info{};
5885         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5886         submit_info.commandBufferCount = 1;
5887         submit_info.pCommandBuffers = &command_buffer[1];
5888         submit_info.waitSemaphoreCount = 1;
5889         submit_info.pWaitSemaphores = &semaphore;
5890         submit_info.pWaitDstStageMask = flags;
5891         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5892     }
5893
5894     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5895
5896     vkDestroyFence(m_device->device(), fence, nullptr);
5897     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5898     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5899     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5900
5901     m_errorMonitor->VerifyNotFound();
5902 }
5903
5904 // This is a positive test.  No errors should be generated.
5905 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
5906
5907     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5908                      "on the same queue, sharing a signal/wait semaphore, the "
5909                      "second having a fence, "
5910                      "followed by a WaitForFences call.");
5911
5912     m_errorMonitor->ExpectSuccess();
5913
5914     ASSERT_NO_FATAL_FAILURE(InitState());
5915     VkFence fence;
5916     VkFenceCreateInfo fence_create_info{};
5917     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5918     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5919
5920     VkSemaphore semaphore;
5921     VkSemaphoreCreateInfo semaphore_create_info{};
5922     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5923     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5924
5925     VkCommandPool command_pool;
5926     VkCommandPoolCreateInfo pool_create_info{};
5927     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5928     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5929     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5930     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5931
5932     VkCommandBuffer command_buffer[2];
5933     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5934     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5935     command_buffer_allocate_info.commandPool = command_pool;
5936     command_buffer_allocate_info.commandBufferCount = 2;
5937     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5938     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5939
5940     {
5941         VkCommandBufferBeginInfo begin_info{};
5942         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5943         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5944
5945         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5946                              nullptr, 0, nullptr, 0, nullptr);
5947
5948         VkViewport viewport{};
5949         viewport.maxDepth = 1.0f;
5950         viewport.minDepth = 0.0f;
5951         viewport.width = 512;
5952         viewport.height = 512;
5953         viewport.x = 0;
5954         viewport.y = 0;
5955         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5956         vkEndCommandBuffer(command_buffer[0]);
5957     }
5958     {
5959         VkCommandBufferBeginInfo begin_info{};
5960         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5961         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5962
5963         VkViewport viewport{};
5964         viewport.maxDepth = 1.0f;
5965         viewport.minDepth = 0.0f;
5966         viewport.width = 512;
5967         viewport.height = 512;
5968         viewport.x = 0;
5969         viewport.y = 0;
5970         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5971         vkEndCommandBuffer(command_buffer[1]);
5972     }
5973     {
5974         VkSubmitInfo submit_info{};
5975         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5976         submit_info.commandBufferCount = 1;
5977         submit_info.pCommandBuffers = &command_buffer[0];
5978         submit_info.signalSemaphoreCount = 1;
5979         submit_info.pSignalSemaphores = &semaphore;
5980         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5981     }
5982     {
5983         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5984         VkSubmitInfo submit_info{};
5985         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5986         submit_info.commandBufferCount = 1;
5987         submit_info.pCommandBuffers = &command_buffer[1];
5988         submit_info.waitSemaphoreCount = 1;
5989         submit_info.pWaitSemaphores = &semaphore;
5990         submit_info.pWaitDstStageMask = flags;
5991         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5992     }
5993
5994     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5995
5996     vkDestroyFence(m_device->device(), fence, nullptr);
5997     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5998     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5999     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6000
6001     m_errorMonitor->VerifyNotFound();
6002 }
6003
6004 // This is a positive test.  No errors should be generated.
6005 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
6006
6007     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6008                      "on the same queue, no fences, followed by a third QueueSubmit with NO "
6009                      "SubmitInfos but with a fence, followed by a WaitForFences call.");
6010
6011     m_errorMonitor->ExpectSuccess();
6012
6013     ASSERT_NO_FATAL_FAILURE(InitState());
6014     VkFence fence;
6015     VkFenceCreateInfo fence_create_info{};
6016     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6017     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6018
6019     VkCommandPool command_pool;
6020     VkCommandPoolCreateInfo pool_create_info{};
6021     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6022     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6023     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6024     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6025
6026     VkCommandBuffer command_buffer[2];
6027     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6028     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6029     command_buffer_allocate_info.commandPool = command_pool;
6030     command_buffer_allocate_info.commandBufferCount = 2;
6031     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6032     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6033
6034     {
6035         VkCommandBufferBeginInfo begin_info{};
6036         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6037         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6038
6039         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6040                              nullptr, 0, nullptr, 0, nullptr);
6041
6042         VkViewport viewport{};
6043         viewport.maxDepth = 1.0f;
6044         viewport.minDepth = 0.0f;
6045         viewport.width = 512;
6046         viewport.height = 512;
6047         viewport.x = 0;
6048         viewport.y = 0;
6049         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6050         vkEndCommandBuffer(command_buffer[0]);
6051     }
6052     {
6053         VkCommandBufferBeginInfo begin_info{};
6054         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6055         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6056
6057         VkViewport viewport{};
6058         viewport.maxDepth = 1.0f;
6059         viewport.minDepth = 0.0f;
6060         viewport.width = 512;
6061         viewport.height = 512;
6062         viewport.x = 0;
6063         viewport.y = 0;
6064         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6065         vkEndCommandBuffer(command_buffer[1]);
6066     }
6067     {
6068         VkSubmitInfo submit_info{};
6069         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6070         submit_info.commandBufferCount = 1;
6071         submit_info.pCommandBuffers = &command_buffer[0];
6072         submit_info.signalSemaphoreCount = 0;
6073         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6074         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6075     }
6076     {
6077         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6078         VkSubmitInfo submit_info{};
6079         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6080         submit_info.commandBufferCount = 1;
6081         submit_info.pCommandBuffers = &command_buffer[1];
6082         submit_info.waitSemaphoreCount = 0;
6083         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6084         submit_info.pWaitDstStageMask = flags;
6085         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6086     }
6087
6088     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
6089
6090     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6091     ASSERT_VK_SUCCESS(err);
6092
6093     vkDestroyFence(m_device->device(), fence, nullptr);
6094     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6095     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6096
6097     m_errorMonitor->VerifyNotFound();
6098 }
6099
6100 // This is a positive test.  No errors should be generated.
6101 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
6102
6103     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6104                      "on the same queue, the second having a fence, followed "
6105                      "by a WaitForFences call.");
6106
6107     m_errorMonitor->ExpectSuccess();
6108
6109     ASSERT_NO_FATAL_FAILURE(InitState());
6110     VkFence fence;
6111     VkFenceCreateInfo fence_create_info{};
6112     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6113     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6114
6115     VkCommandPool command_pool;
6116     VkCommandPoolCreateInfo pool_create_info{};
6117     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6118     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6119     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6120     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6121
6122     VkCommandBuffer command_buffer[2];
6123     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6124     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6125     command_buffer_allocate_info.commandPool = command_pool;
6126     command_buffer_allocate_info.commandBufferCount = 2;
6127     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6128     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6129
6130     {
6131         VkCommandBufferBeginInfo begin_info{};
6132         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6133         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6134
6135         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6136                              nullptr, 0, nullptr, 0, nullptr);
6137
6138         VkViewport viewport{};
6139         viewport.maxDepth = 1.0f;
6140         viewport.minDepth = 0.0f;
6141         viewport.width = 512;
6142         viewport.height = 512;
6143         viewport.x = 0;
6144         viewport.y = 0;
6145         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6146         vkEndCommandBuffer(command_buffer[0]);
6147     }
6148     {
6149         VkCommandBufferBeginInfo begin_info{};
6150         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6151         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6152
6153         VkViewport viewport{};
6154         viewport.maxDepth = 1.0f;
6155         viewport.minDepth = 0.0f;
6156         viewport.width = 512;
6157         viewport.height = 512;
6158         viewport.x = 0;
6159         viewport.y = 0;
6160         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6161         vkEndCommandBuffer(command_buffer[1]);
6162     }
6163     {
6164         VkSubmitInfo submit_info{};
6165         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6166         submit_info.commandBufferCount = 1;
6167         submit_info.pCommandBuffers = &command_buffer[0];
6168         submit_info.signalSemaphoreCount = 0;
6169         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6170         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6171     }
6172     {
6173         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6174         VkSubmitInfo submit_info{};
6175         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6176         submit_info.commandBufferCount = 1;
6177         submit_info.pCommandBuffers = &command_buffer[1];
6178         submit_info.waitSemaphoreCount = 0;
6179         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6180         submit_info.pWaitDstStageMask = flags;
6181         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
6182     }
6183
6184     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6185
6186     vkDestroyFence(m_device->device(), fence, nullptr);
6187     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6188     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6189
6190     m_errorMonitor->VerifyNotFound();
6191 }
6192
6193 // This is a positive test.  No errors should be generated.
6194 TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
6195
6196     TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
6197                      "QueueSubmit call followed by a WaitForFences call.");
6198     ASSERT_NO_FATAL_FAILURE(InitState());
6199
6200     m_errorMonitor->ExpectSuccess();
6201
6202     VkFence fence;
6203     VkFenceCreateInfo fence_create_info{};
6204     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6205     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6206
6207     VkSemaphore semaphore;
6208     VkSemaphoreCreateInfo semaphore_create_info{};
6209     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6210     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
6211
6212     VkCommandPool command_pool;
6213     VkCommandPoolCreateInfo pool_create_info{};
6214     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6215     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6216     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6217     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6218
6219     VkCommandBuffer command_buffer[2];
6220     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6221     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6222     command_buffer_allocate_info.commandPool = command_pool;
6223     command_buffer_allocate_info.commandBufferCount = 2;
6224     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6225     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6226
6227     {
6228         VkCommandBufferBeginInfo begin_info{};
6229         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6230         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6231
6232         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6233                              nullptr, 0, nullptr, 0, nullptr);
6234
6235         VkViewport viewport{};
6236         viewport.maxDepth = 1.0f;
6237         viewport.minDepth = 0.0f;
6238         viewport.width = 512;
6239         viewport.height = 512;
6240         viewport.x = 0;
6241         viewport.y = 0;
6242         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6243         vkEndCommandBuffer(command_buffer[0]);
6244     }
6245     {
6246         VkCommandBufferBeginInfo begin_info{};
6247         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6248         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6249
6250         VkViewport viewport{};
6251         viewport.maxDepth = 1.0f;
6252         viewport.minDepth = 0.0f;
6253         viewport.width = 512;
6254         viewport.height = 512;
6255         viewport.x = 0;
6256         viewport.y = 0;
6257         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6258         vkEndCommandBuffer(command_buffer[1]);
6259     }
6260     {
6261         VkSubmitInfo submit_info[2];
6262         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6263
6264         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6265         submit_info[0].pNext = NULL;
6266         submit_info[0].commandBufferCount = 1;
6267         submit_info[0].pCommandBuffers = &command_buffer[0];
6268         submit_info[0].signalSemaphoreCount = 1;
6269         submit_info[0].pSignalSemaphores = &semaphore;
6270         submit_info[0].waitSemaphoreCount = 0;
6271         submit_info[0].pWaitSemaphores = NULL;
6272         submit_info[0].pWaitDstStageMask = 0;
6273
6274         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6275         submit_info[1].pNext = NULL;
6276         submit_info[1].commandBufferCount = 1;
6277         submit_info[1].pCommandBuffers = &command_buffer[1];
6278         submit_info[1].waitSemaphoreCount = 1;
6279         submit_info[1].pWaitSemaphores = &semaphore;
6280         submit_info[1].pWaitDstStageMask = flags;
6281         submit_info[1].signalSemaphoreCount = 0;
6282         submit_info[1].pSignalSemaphores = NULL;
6283         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
6284     }
6285
6286     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6287
6288     vkDestroyFence(m_device->device(), fence, nullptr);
6289     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6290     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6291     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6292
6293     m_errorMonitor->VerifyNotFound();
6294 }
6295
6296 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
6297     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
6298                      "state is required but not correctly bound.");
6299
6300     ASSERT_NO_FATAL_FAILURE(InitState());
6301     // Dynamic depth bias
6302     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
6303     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias);
6304     m_errorMonitor->VerifyFound();
6305 }
6306
6307 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
6308     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic "
6309                      "state is required but not correctly bound.");
6310
6311     ASSERT_NO_FATAL_FAILURE(InitState());
6312     // Dynamic line width
6313     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
6314     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth);
6315     m_errorMonitor->VerifyFound();
6316 }
6317
6318 TEST_F(VkLayerTest, DynamicViewportNotBound) {
6319     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic "
6320                      "state is required but not correctly bound.");
6321
6322     ASSERT_NO_FATAL_FAILURE(InitState());
6323     // Dynamic viewport state
6324     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, but were not provided");
6325     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
6326     m_errorMonitor->VerifyFound();
6327 }
6328
6329 TEST_F(VkLayerTest, DynamicScissorNotBound) {
6330     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic "
6331                      "state is required but not correctly bound.");
6332
6333     ASSERT_NO_FATAL_FAILURE(InitState());
6334     // Dynamic scissor state
6335     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, but were not provided");
6336     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
6337     m_errorMonitor->VerifyFound();
6338 }
6339
6340 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
6341     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants "
6342                      "dynamic state is required but not correctly bound.");
6343
6344     ASSERT_NO_FATAL_FAILURE(InitState());
6345     // Dynamic blend constant state
6346     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6347                                          "Dynamic blend constants state not set for this command buffer");
6348     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend);
6349     m_errorMonitor->VerifyFound();
6350 }
6351
6352 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
6353     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic "
6354                      "state is required but not correctly bound.");
6355
6356     ASSERT_NO_FATAL_FAILURE(InitState());
6357     if (!m_device->phy().features().depthBounds) {
6358         printf("Device does not support depthBounds test; skipped.\n");
6359         return;
6360     }
6361     // Dynamic depth bounds
6362     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6363                                          "Dynamic depth bounds state not set for this command buffer");
6364     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds);
6365     m_errorMonitor->VerifyFound();
6366 }
6367
6368 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
6369     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic "
6370                      "state is required but not correctly bound.");
6371
6372     ASSERT_NO_FATAL_FAILURE(InitState());
6373     // Dynamic stencil read mask
6374     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6375                                          "Dynamic stencil read mask state not set for this command buffer");
6376     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask);
6377     m_errorMonitor->VerifyFound();
6378 }
6379
6380 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
6381     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic"
6382                      " state is required but not correctly bound.");
6383
6384     ASSERT_NO_FATAL_FAILURE(InitState());
6385     // Dynamic stencil write mask
6386     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6387                                          "Dynamic stencil write mask state not set for this command buffer");
6388     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask);
6389     m_errorMonitor->VerifyFound();
6390 }
6391
6392 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
6393     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic "
6394                      "state is required but not correctly bound.");
6395
6396     ASSERT_NO_FATAL_FAILURE(InitState());
6397     // Dynamic stencil reference
6398     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6399                                          "Dynamic stencil reference state not set for this command buffer");
6400     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference);
6401     m_errorMonitor->VerifyFound();
6402 }
6403
6404 TEST_F(VkLayerTest, IndexBufferNotBound) {
6405     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
6406
6407     ASSERT_NO_FATAL_FAILURE(InitState());
6408     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6409                                          "Index buffer object not bound to this command buffer when Indexed ");
6410     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer);
6411     m_errorMonitor->VerifyFound();
6412 }
6413
6414 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
6415     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6416                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
6417                                          "been submitted");
6418
6419     ASSERT_NO_FATAL_FAILURE(InitState());
6420     ASSERT_NO_FATAL_FAILURE(InitViewport());
6421     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6422
6423     // We luck out b/c by default the framework creates CB w/ the
6424     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
6425     BeginCommandBuffer();
6426     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
6427     EndCommandBuffer();
6428
6429     // Bypass framework since it does the waits automatically
6430     VkResult err = VK_SUCCESS;
6431     VkSubmitInfo submit_info;
6432     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6433     submit_info.pNext = NULL;
6434     submit_info.waitSemaphoreCount = 0;
6435     submit_info.pWaitSemaphores = NULL;
6436     submit_info.pWaitDstStageMask = NULL;
6437     submit_info.commandBufferCount = 1;
6438     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6439     submit_info.signalSemaphoreCount = 0;
6440     submit_info.pSignalSemaphores = NULL;
6441
6442     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6443     ASSERT_VK_SUCCESS(err);
6444
6445     // Cause validation error by re-submitting cmd buffer that should only be
6446     // submitted once
6447     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6448
6449     m_errorMonitor->VerifyFound();
6450 }
6451
6452 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
6453     // Initiate Draw w/o a PSO bound
6454     VkResult err;
6455
6456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of "
6457                                                                         "type "
6458                                                                         "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ");
6459
6460     ASSERT_NO_FATAL_FAILURE(InitState());
6461     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6462
6463     // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
6464     // descriptor from it
6465     VkDescriptorPoolSize ds_type_count = {};
6466     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
6467     ds_type_count.descriptorCount = 1;
6468
6469     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6470     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6471     ds_pool_ci.pNext = NULL;
6472     ds_pool_ci.flags = 0;
6473     ds_pool_ci.maxSets = 1;
6474     ds_pool_ci.poolSizeCount = 1;
6475     ds_pool_ci.pPoolSizes = &ds_type_count;
6476
6477     VkDescriptorPool ds_pool;
6478     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6479     ASSERT_VK_SUCCESS(err);
6480
6481     VkDescriptorSetLayoutBinding dsl_binding = {};
6482     dsl_binding.binding = 0;
6483     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6484     dsl_binding.descriptorCount = 1;
6485     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6486     dsl_binding.pImmutableSamplers = NULL;
6487
6488     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6489     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6490     ds_layout_ci.pNext = NULL;
6491     ds_layout_ci.bindingCount = 1;
6492     ds_layout_ci.pBindings = &dsl_binding;
6493
6494     VkDescriptorSetLayout ds_layout;
6495     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6496     ASSERT_VK_SUCCESS(err);
6497
6498     VkDescriptorSet descriptorSet;
6499     VkDescriptorSetAllocateInfo alloc_info = {};
6500     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6501     alloc_info.descriptorSetCount = 1;
6502     alloc_info.descriptorPool = ds_pool;
6503     alloc_info.pSetLayouts = &ds_layout;
6504     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6505
6506     m_errorMonitor->VerifyFound();
6507
6508     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6509     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6510 }
6511
6512 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
6513     VkResult err;
6514
6515     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6516                                          "It is invalid to call vkFreeDescriptorSets() with a pool created "
6517                                          "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
6518
6519     ASSERT_NO_FATAL_FAILURE(InitState());
6520     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6521
6522     VkDescriptorPoolSize ds_type_count = {};
6523     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6524     ds_type_count.descriptorCount = 1;
6525
6526     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6527     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6528     ds_pool_ci.pNext = NULL;
6529     ds_pool_ci.maxSets = 1;
6530     ds_pool_ci.poolSizeCount = 1;
6531     ds_pool_ci.flags = 0;
6532     // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
6533     // app can only call vkResetDescriptorPool on this pool.;
6534     ds_pool_ci.pPoolSizes = &ds_type_count;
6535
6536     VkDescriptorPool ds_pool;
6537     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6538     ASSERT_VK_SUCCESS(err);
6539
6540     VkDescriptorSetLayoutBinding dsl_binding = {};
6541     dsl_binding.binding = 0;
6542     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6543     dsl_binding.descriptorCount = 1;
6544     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6545     dsl_binding.pImmutableSamplers = NULL;
6546
6547     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6548     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6549     ds_layout_ci.pNext = NULL;
6550     ds_layout_ci.bindingCount = 1;
6551     ds_layout_ci.pBindings = &dsl_binding;
6552
6553     VkDescriptorSetLayout ds_layout;
6554     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6555     ASSERT_VK_SUCCESS(err);
6556
6557     VkDescriptorSet descriptorSet;
6558     VkDescriptorSetAllocateInfo alloc_info = {};
6559     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6560     alloc_info.descriptorSetCount = 1;
6561     alloc_info.descriptorPool = ds_pool;
6562     alloc_info.pSetLayouts = &ds_layout;
6563     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6564     ASSERT_VK_SUCCESS(err);
6565
6566     err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
6567     m_errorMonitor->VerifyFound();
6568
6569     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6570     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6571 }
6572
6573 TEST_F(VkLayerTest, InvalidDescriptorPool) {
6574     // Attempt to clear Descriptor Pool with bad object.
6575     // ObjectTracker should catch this.
6576
6577     ASSERT_NO_FATAL_FAILURE(InitState());
6578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001");
6579     uint64_t fake_pool_handle = 0xbaad6001;
6580     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
6581     vkResetDescriptorPool(device(), bad_pool, 0);
6582     m_errorMonitor->VerifyFound();
6583 }
6584
6585 TEST_F(VkLayerTest, InvalidDescriptorSet) {
6586     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
6587     // ObjectTracker should catch this.
6588     // Create a valid cmd buffer
6589     // call vkCmdBindDescriptorSets w/ false Descriptor Set
6590
6591     uint64_t fake_set_handle = 0xbaad6001;
6592     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
6593     VkResult err;
6594     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001");
6595
6596     ASSERT_NO_FATAL_FAILURE(InitState());
6597
6598     VkDescriptorSetLayoutBinding layout_bindings[1] = {};
6599     layout_bindings[0].binding = 0;
6600     layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6601     layout_bindings[0].descriptorCount = 1;
6602     layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
6603     layout_bindings[0].pImmutableSamplers = NULL;
6604
6605     VkDescriptorSetLayout descriptor_set_layout;
6606     VkDescriptorSetLayoutCreateInfo dslci = {};
6607     dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6608     dslci.pNext = NULL;
6609     dslci.bindingCount = 1;
6610     dslci.pBindings = layout_bindings;
6611     err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout);
6612     ASSERT_VK_SUCCESS(err);
6613
6614     VkPipelineLayout pipeline_layout;
6615     VkPipelineLayoutCreateInfo plci = {};
6616     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6617     plci.pNext = NULL;
6618     plci.setLayoutCount = 1;
6619     plci.pSetLayouts = &descriptor_set_layout;
6620     err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6621     ASSERT_VK_SUCCESS(err);
6622
6623     BeginCommandBuffer();
6624     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0,
6625                             NULL);
6626     m_errorMonitor->VerifyFound();
6627     EndCommandBuffer();
6628     vkDestroyPipelineLayout(device(), pipeline_layout, NULL);
6629     vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL);
6630 }
6631
6632 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
6633     // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
6634     // ObjectTracker should catch this.
6635     uint64_t fake_layout_handle = 0xbaad6001;
6636     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
6637     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001");
6638     ASSERT_NO_FATAL_FAILURE(InitState());
6639     VkPipelineLayout pipeline_layout;
6640     VkPipelineLayoutCreateInfo plci = {};
6641     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6642     plci.pNext = NULL;
6643     plci.setLayoutCount = 1;
6644     plci.pSetLayouts = &bad_layout;
6645     vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6646
6647     m_errorMonitor->VerifyFound();
6648 }
6649
6650 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
6651     TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
6652                      "1) A uniform buffer update must have a valid buffer index."
6653                      "2) When using an array of descriptors in a single WriteDescriptor,"
6654                      "     the descriptor types and stageflags must all be the same."
6655                      "3) Immutable Sampler state must match across descriptors");
6656
6657     const char *invalid_BufferInfo_ErrorMessage =
6658         "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
6659         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
6660         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
6661     const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set ";
6662     const char *immutable_ErrorMessage = "Attempting write update to descriptor set ";
6663
6664     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
6665
6666     ASSERT_NO_FATAL_FAILURE(InitState());
6667     VkDescriptorPoolSize ds_type_count[4] = {};
6668     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6669     ds_type_count[0].descriptorCount = 1;
6670     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6671     ds_type_count[1].descriptorCount = 1;
6672     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6673     ds_type_count[2].descriptorCount = 1;
6674     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
6675     ds_type_count[3].descriptorCount = 1;
6676
6677     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6678     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6679     ds_pool_ci.maxSets = 1;
6680     ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
6681     ds_pool_ci.pPoolSizes = ds_type_count;
6682
6683     VkDescriptorPool ds_pool;
6684     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6685     ASSERT_VK_SUCCESS(err);
6686
6687     VkDescriptorSetLayoutBinding layout_binding[3] = {};
6688     layout_binding[0].binding = 0;
6689     layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6690     layout_binding[0].descriptorCount = 1;
6691     layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
6692     layout_binding[0].pImmutableSamplers = NULL;
6693
6694     layout_binding[1].binding = 1;
6695     layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6696     layout_binding[1].descriptorCount = 1;
6697     layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6698     layout_binding[1].pImmutableSamplers = NULL;
6699
6700     VkSamplerCreateInfo sampler_ci = {};
6701     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6702     sampler_ci.pNext = NULL;
6703     sampler_ci.magFilter = VK_FILTER_NEAREST;
6704     sampler_ci.minFilter = VK_FILTER_NEAREST;
6705     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
6706     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6707     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6708     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6709     sampler_ci.mipLodBias = 1.0;
6710     sampler_ci.anisotropyEnable = VK_FALSE;
6711     sampler_ci.maxAnisotropy = 1;
6712     sampler_ci.compareEnable = VK_FALSE;
6713     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
6714     sampler_ci.minLod = 1.0;
6715     sampler_ci.maxLod = 1.0;
6716     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
6717     sampler_ci.unnormalizedCoordinates = VK_FALSE;
6718     VkSampler sampler;
6719
6720     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
6721     ASSERT_VK_SUCCESS(err);
6722
6723     layout_binding[2].binding = 2;
6724     layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6725     layout_binding[2].descriptorCount = 1;
6726     layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6727     layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
6728
6729     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6730     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6731     ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
6732     ds_layout_ci.pBindings = layout_binding;
6733     VkDescriptorSetLayout ds_layout;
6734     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6735     ASSERT_VK_SUCCESS(err);
6736
6737     VkDescriptorSetAllocateInfo alloc_info = {};
6738     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6739     alloc_info.descriptorSetCount = 1;
6740     alloc_info.descriptorPool = ds_pool;
6741     alloc_info.pSetLayouts = &ds_layout;
6742     VkDescriptorSet descriptorSet;
6743     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6744     ASSERT_VK_SUCCESS(err);
6745
6746     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6747     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6748     pipeline_layout_ci.pNext = NULL;
6749     pipeline_layout_ci.setLayoutCount = 1;
6750     pipeline_layout_ci.pSetLayouts = &ds_layout;
6751
6752     VkPipelineLayout pipeline_layout;
6753     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6754     ASSERT_VK_SUCCESS(err);
6755
6756     VkWriteDescriptorSet descriptor_write = {};
6757     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6758     descriptor_write.dstSet = descriptorSet;
6759     descriptor_write.dstBinding = 0;
6760     descriptor_write.descriptorCount = 1;
6761     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6762
6763     // 1) The uniform buffer is intentionally invalid here
6764     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6765     m_errorMonitor->VerifyFound();
6766
6767     // Create a buffer to update the descriptor with
6768     uint32_t qfi = 0;
6769     VkBufferCreateInfo buffCI = {};
6770     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6771     buffCI.size = 1024;
6772     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
6773     buffCI.queueFamilyIndexCount = 1;
6774     buffCI.pQueueFamilyIndices = &qfi;
6775
6776     VkBuffer dyub;
6777     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
6778     ASSERT_VK_SUCCESS(err);
6779     VkDescriptorBufferInfo buffInfo = {};
6780     buffInfo.buffer = dyub;
6781     buffInfo.offset = 0;
6782     buffInfo.range = 1024;
6783
6784     descriptor_write.pBufferInfo = &buffInfo;
6785     descriptor_write.descriptorCount = 2;
6786
6787     // 2) The stateFlags don't match between the first and second descriptor
6788     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
6789     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6790     m_errorMonitor->VerifyFound();
6791
6792     // 3) The second descriptor has a null_ptr pImmutableSamplers and
6793     // the third descriptor contains an immutable sampler
6794     descriptor_write.dstBinding = 1;
6795     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6796
6797     // Make pImageInfo index non-null to avoid complaints of it missing
6798     VkDescriptorImageInfo imageInfo = {};
6799     imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6800     descriptor_write.pImageInfo = &imageInfo;
6801     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
6802     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6803     m_errorMonitor->VerifyFound();
6804
6805     vkDestroyBuffer(m_device->device(), dyub, NULL);
6806     vkDestroySampler(m_device->device(), sampler, NULL);
6807     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
6808     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6809     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6810 }
6811
6812 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
6813     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
6814                      "due to a buffer dependency being destroyed.");
6815     ASSERT_NO_FATAL_FAILURE(InitState());
6816
6817     VkBuffer buffer;
6818     VkDeviceMemory mem;
6819     VkMemoryRequirements mem_reqs;
6820
6821     VkBufferCreateInfo buf_info = {};
6822     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6823     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
6824     buf_info.size = 256;
6825     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
6826     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
6827     ASSERT_VK_SUCCESS(err);
6828
6829     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
6830
6831     VkMemoryAllocateInfo alloc_info = {};
6832     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6833     alloc_info.allocationSize = 256;
6834     bool pass = false;
6835     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6836     if (!pass) {
6837         vkDestroyBuffer(m_device->device(), buffer, NULL);
6838         return;
6839     }
6840     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
6841     ASSERT_VK_SUCCESS(err);
6842
6843     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
6844     ASSERT_VK_SUCCESS(err);
6845
6846     m_commandBuffer->BeginCommandBuffer();
6847     vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
6848     m_commandBuffer->EndCommandBuffer();
6849
6850     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
6851     // Destroy buffer dependency prior to submit to cause ERROR
6852     vkDestroyBuffer(m_device->device(), buffer, NULL);
6853
6854     VkSubmitInfo submit_info = {};
6855     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6856     submit_info.commandBufferCount = 1;
6857     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6858     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6859
6860     m_errorMonitor->VerifyFound();
6861     vkFreeMemory(m_device->handle(), mem, NULL);
6862 }
6863
6864 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
6865     TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
6866
6867     ASSERT_NO_FATAL_FAILURE(InitState());
6868     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6869
6870     VkDescriptorPoolSize ds_type_count;
6871     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6872     ds_type_count.descriptorCount = 1;
6873
6874     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6875     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6876     ds_pool_ci.maxSets = 1;
6877     ds_pool_ci.poolSizeCount = 1;
6878     ds_pool_ci.pPoolSizes = &ds_type_count;
6879
6880     VkDescriptorPool ds_pool;
6881     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6882     ASSERT_VK_SUCCESS(err);
6883
6884     VkDescriptorSetLayoutBinding layout_binding;
6885     layout_binding.binding = 0;
6886     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6887     layout_binding.descriptorCount = 1;
6888     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6889     layout_binding.pImmutableSamplers = NULL;
6890
6891     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6892     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6893     ds_layout_ci.bindingCount = 1;
6894     ds_layout_ci.pBindings = &layout_binding;
6895     VkDescriptorSetLayout ds_layout;
6896     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6897     ASSERT_VK_SUCCESS(err);
6898
6899     VkDescriptorSetAllocateInfo alloc_info = {};
6900     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6901     alloc_info.descriptorSetCount = 1;
6902     alloc_info.descriptorPool = ds_pool;
6903     alloc_info.pSetLayouts = &ds_layout;
6904     VkDescriptorSet descriptor_set;
6905     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
6906     ASSERT_VK_SUCCESS(err);
6907
6908     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6909     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6910     pipeline_layout_ci.pNext = NULL;
6911     pipeline_layout_ci.setLayoutCount = 1;
6912     pipeline_layout_ci.pSetLayouts = &ds_layout;
6913
6914     VkPipelineLayout pipeline_layout;
6915     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6916     ASSERT_VK_SUCCESS(err);
6917
6918     VkBuffer buffer;
6919     uint32_t queue_family_index = 0;
6920     VkBufferCreateInfo buffer_create_info = {};
6921     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6922     buffer_create_info.size = 1024;
6923     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
6924     buffer_create_info.queueFamilyIndexCount = 1;
6925     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
6926
6927     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
6928     ASSERT_VK_SUCCESS(err);
6929
6930     VkMemoryRequirements memory_reqs;
6931     VkDeviceMemory buffer_memory;
6932
6933     VkMemoryAllocateInfo memory_info = {};
6934     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6935     memory_info.allocationSize = 0;
6936     memory_info.memoryTypeIndex = 0;
6937
6938     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
6939     memory_info.allocationSize = memory_reqs.size;
6940     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
6941     ASSERT_TRUE(pass);
6942
6943     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
6944     ASSERT_VK_SUCCESS(err);
6945     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
6946     ASSERT_VK_SUCCESS(err);
6947
6948     VkBufferView view;
6949     VkBufferViewCreateInfo bvci = {};
6950     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
6951     bvci.buffer = buffer;
6952     bvci.format = VK_FORMAT_R8_UNORM;
6953     bvci.range = VK_WHOLE_SIZE;
6954
6955     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
6956     ASSERT_VK_SUCCESS(err);
6957
6958     VkWriteDescriptorSet descriptor_write = {};
6959     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6960     descriptor_write.dstSet = descriptor_set;
6961     descriptor_write.dstBinding = 0;
6962     descriptor_write.descriptorCount = 1;
6963     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6964     descriptor_write.pTexelBufferView = &view;
6965
6966     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6967
6968     char const *vsSource = "#version 450\n"
6969                            "\n"
6970                            "out gl_PerVertex { \n"
6971                            "    vec4 gl_Position;\n"
6972                            "};\n"
6973                            "void main(){\n"
6974                            "   gl_Position = vec4(1);\n"
6975                            "}\n";
6976     char const *fsSource = "#version 450\n"
6977                            "\n"
6978                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
6979                            "layout(location=0) out vec4 x;\n"
6980                            "void main(){\n"
6981                            "   x = imageLoad(s, 0);\n"
6982                            "}\n";
6983     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
6984     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6985     VkPipelineObj pipe(m_device);
6986     pipe.AddShader(&vs);
6987     pipe.AddShader(&fs);
6988     pipe.AddColorAttachment();
6989     pipe.CreateVKPipeline(pipeline_layout, renderPass());
6990
6991     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
6992     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
6993
6994     BeginCommandBuffer();
6995     VkViewport viewport = {0, 0, 16, 16, 0, 1};
6996     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
6997     VkRect2D scissor = {{0, 0}, {16, 16}};
6998     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
6999     // Bind pipeline to cmd buffer
7000     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7001     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7002                             &descriptor_set, 0, nullptr);
7003     Draw(1, 0, 0, 0);
7004     EndCommandBuffer();
7005
7006     // Delete BufferView in order to invalidate cmd buffer
7007     vkDestroyBufferView(m_device->device(), view, NULL);
7008     // Now attempt submit of cmd buffer
7009     VkSubmitInfo submit_info = {};
7010     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7011     submit_info.commandBufferCount = 1;
7012     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7013     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7014     m_errorMonitor->VerifyFound();
7015
7016     // Clean-up
7017     vkDestroyBuffer(m_device->device(), buffer, NULL);
7018     vkFreeMemory(m_device->device(), buffer_memory, NULL);
7019     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7020     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7021     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7022 }
7023
7024 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
7025     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7026                      "due to an image dependency being destroyed.");
7027     ASSERT_NO_FATAL_FAILURE(InitState());
7028
7029     VkImage image;
7030     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7031     VkImageCreateInfo image_create_info = {};
7032     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7033     image_create_info.pNext = NULL;
7034     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7035     image_create_info.format = tex_format;
7036     image_create_info.extent.width = 32;
7037     image_create_info.extent.height = 32;
7038     image_create_info.extent.depth = 1;
7039     image_create_info.mipLevels = 1;
7040     image_create_info.arrayLayers = 1;
7041     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7042     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7043     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7044     image_create_info.flags = 0;
7045     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7046     ASSERT_VK_SUCCESS(err);
7047     // Have to bind memory to image before recording cmd in cmd buffer using it
7048     VkMemoryRequirements mem_reqs;
7049     VkDeviceMemory image_mem;
7050     bool pass;
7051     VkMemoryAllocateInfo mem_alloc = {};
7052     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7053     mem_alloc.pNext = NULL;
7054     mem_alloc.memoryTypeIndex = 0;
7055     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7056     mem_alloc.allocationSize = mem_reqs.size;
7057     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7058     ASSERT_TRUE(pass);
7059     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7060     ASSERT_VK_SUCCESS(err);
7061     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
7062     ASSERT_VK_SUCCESS(err);
7063
7064     m_commandBuffer->BeginCommandBuffer();
7065     VkClearColorValue ccv;
7066     ccv.float32[0] = 1.0f;
7067     ccv.float32[1] = 1.0f;
7068     ccv.float32[2] = 1.0f;
7069     ccv.float32[3] = 1.0f;
7070     VkImageSubresourceRange isr = {};
7071     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7072     isr.baseArrayLayer = 0;
7073     isr.baseMipLevel = 0;
7074     isr.layerCount = 1;
7075     isr.levelCount = 1;
7076     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7077     m_commandBuffer->EndCommandBuffer();
7078
7079     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7080     // Destroy image dependency prior to submit to cause ERROR
7081     vkDestroyImage(m_device->device(), image, NULL);
7082
7083     VkSubmitInfo submit_info = {};
7084     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7085     submit_info.commandBufferCount = 1;
7086     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7087     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7088
7089     m_errorMonitor->VerifyFound();
7090     vkFreeMemory(m_device->device(), image_mem, nullptr);
7091 }
7092
7093 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
7094     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7095                      "due to a framebuffer image dependency being destroyed.");
7096     VkFormatProperties format_properties;
7097     VkResult err = VK_SUCCESS;
7098     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7099     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
7100         return;
7101     }
7102
7103     ASSERT_NO_FATAL_FAILURE(InitState());
7104     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7105
7106     VkImageCreateInfo image_ci = {};
7107     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7108     image_ci.pNext = NULL;
7109     image_ci.imageType = VK_IMAGE_TYPE_2D;
7110     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7111     image_ci.extent.width = 32;
7112     image_ci.extent.height = 32;
7113     image_ci.extent.depth = 1;
7114     image_ci.mipLevels = 1;
7115     image_ci.arrayLayers = 1;
7116     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7117     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7118     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7119     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7120     image_ci.flags = 0;
7121     VkImage image;
7122     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7123
7124     VkMemoryRequirements memory_reqs;
7125     VkDeviceMemory image_memory;
7126     bool pass;
7127     VkMemoryAllocateInfo memory_info = {};
7128     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7129     memory_info.pNext = NULL;
7130     memory_info.allocationSize = 0;
7131     memory_info.memoryTypeIndex = 0;
7132     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7133     memory_info.allocationSize = memory_reqs.size;
7134     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7135     ASSERT_TRUE(pass);
7136     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7137     ASSERT_VK_SUCCESS(err);
7138     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7139     ASSERT_VK_SUCCESS(err);
7140
7141     VkImageViewCreateInfo ivci = {
7142         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7143         nullptr,
7144         0,
7145         image,
7146         VK_IMAGE_VIEW_TYPE_2D,
7147         VK_FORMAT_B8G8R8A8_UNORM,
7148         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7149         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7150     };
7151     VkImageView view;
7152     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7153     ASSERT_VK_SUCCESS(err);
7154
7155     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
7156     VkFramebuffer fb;
7157     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7158     ASSERT_VK_SUCCESS(err);
7159
7160     // Just use default renderpass with our framebuffer
7161     m_renderPassBeginInfo.framebuffer = fb;
7162     // Create Null cmd buffer for submit
7163     BeginCommandBuffer();
7164     EndCommandBuffer();
7165     // Destroy image attached to framebuffer to invalidate cmd buffer
7166     vkDestroyImage(m_device->device(), image, NULL);
7167     // Now attempt to submit cmd buffer and verify error
7168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7169     QueueCommandBuffer(false);
7170     m_errorMonitor->VerifyFound();
7171
7172     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7173     vkDestroyImageView(m_device->device(), view, nullptr);
7174     vkFreeMemory(m_device->device(), image_memory, nullptr);
7175 }
7176
7177 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
7178     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
7179     VkFormatProperties format_properties;
7180     VkResult err = VK_SUCCESS;
7181     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7182
7183     ASSERT_NO_FATAL_FAILURE(InitState());
7184     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7185
7186     VkImageCreateInfo image_ci = {};
7187     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7188     image_ci.pNext = NULL;
7189     image_ci.imageType = VK_IMAGE_TYPE_2D;
7190     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7191     image_ci.extent.width = 256;
7192     image_ci.extent.height = 256;
7193     image_ci.extent.depth = 1;
7194     image_ci.mipLevels = 1;
7195     image_ci.arrayLayers = 1;
7196     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7197     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7198     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
7199     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7200     image_ci.flags = 0;
7201     VkImage image;
7202     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7203
7204     VkMemoryRequirements memory_reqs;
7205     VkDeviceMemory image_memory;
7206     bool pass;
7207     VkMemoryAllocateInfo memory_info = {};
7208     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7209     memory_info.pNext = NULL;
7210     memory_info.allocationSize = 0;
7211     memory_info.memoryTypeIndex = 0;
7212     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7213     memory_info.allocationSize = memory_reqs.size;
7214     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7215     ASSERT_TRUE(pass);
7216     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7217     ASSERT_VK_SUCCESS(err);
7218     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7219     ASSERT_VK_SUCCESS(err);
7220
7221     VkImageViewCreateInfo ivci = {
7222         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7223         nullptr,
7224         0,
7225         image,
7226         VK_IMAGE_VIEW_TYPE_2D,
7227         VK_FORMAT_B8G8R8A8_UNORM,
7228         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7229         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7230     };
7231     VkImageView view;
7232     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7233     ASSERT_VK_SUCCESS(err);
7234
7235     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
7236     VkFramebuffer fb;
7237     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7238     ASSERT_VK_SUCCESS(err);
7239
7240     // Just use default renderpass with our framebuffer
7241     m_renderPassBeginInfo.framebuffer = fb;
7242     // Create Null cmd buffer for submit
7243     BeginCommandBuffer();
7244     EndCommandBuffer();
7245     // Submit cmd buffer to put it (and attached imageView) in-flight
7246     VkSubmitInfo submit_info = {};
7247     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7248     submit_info.commandBufferCount = 1;
7249     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7250     // Submit cmd buffer to put framebuffer and children in-flight
7251     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7252     // Destroy image attached to framebuffer while in-flight
7253     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
7254     vkDestroyImage(m_device->device(), image, NULL);
7255     m_errorMonitor->VerifyFound();
7256     // Wait for queue to complete so we can safely destroy image and other objects
7257     vkQueueWaitIdle(m_device->m_queue);
7258     vkDestroyImage(m_device->device(), image, NULL);
7259     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7260     vkDestroyImageView(m_device->device(), view, nullptr);
7261     vkFreeMemory(m_device->device(), image_memory, nullptr);
7262 }
7263
7264 TEST_F(VkLayerTest, ImageMemoryNotBound) {
7265     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
7266     ASSERT_NO_FATAL_FAILURE(InitState());
7267
7268     VkImage image;
7269     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7270     VkImageCreateInfo image_create_info = {};
7271     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7272     image_create_info.pNext = NULL;
7273     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7274     image_create_info.format = tex_format;
7275     image_create_info.extent.width = 32;
7276     image_create_info.extent.height = 32;
7277     image_create_info.extent.depth = 1;
7278     image_create_info.mipLevels = 1;
7279     image_create_info.arrayLayers = 1;
7280     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7281     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7282     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7283     image_create_info.flags = 0;
7284     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7285     ASSERT_VK_SUCCESS(err);
7286     // Have to bind memory to image before recording cmd in cmd buffer using it
7287     VkMemoryRequirements mem_reqs;
7288     VkDeviceMemory image_mem;
7289     bool pass;
7290     VkMemoryAllocateInfo mem_alloc = {};
7291     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7292     mem_alloc.pNext = NULL;
7293     mem_alloc.memoryTypeIndex = 0;
7294     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7295     mem_alloc.allocationSize = mem_reqs.size;
7296     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7297     ASSERT_TRUE(pass);
7298     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7299     ASSERT_VK_SUCCESS(err);
7300
7301     // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
7302     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7303                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
7304
7305     m_commandBuffer->BeginCommandBuffer();
7306     VkClearColorValue ccv;
7307     ccv.float32[0] = 1.0f;
7308     ccv.float32[1] = 1.0f;
7309     ccv.float32[2] = 1.0f;
7310     ccv.float32[3] = 1.0f;
7311     VkImageSubresourceRange isr = {};
7312     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7313     isr.baseArrayLayer = 0;
7314     isr.baseMipLevel = 0;
7315     isr.layerCount = 1;
7316     isr.levelCount = 1;
7317     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7318     m_commandBuffer->EndCommandBuffer();
7319
7320     m_errorMonitor->VerifyFound();
7321     vkDestroyImage(m_device->device(), image, NULL);
7322     vkFreeMemory(m_device->device(), image_mem, nullptr);
7323 }
7324
7325 TEST_F(VkLayerTest, BufferMemoryNotBound) {
7326     TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
7327     ASSERT_NO_FATAL_FAILURE(InitState());
7328
7329     VkImageObj image(m_device);
7330     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7331                VK_IMAGE_TILING_OPTIMAL, 0);
7332     ASSERT_TRUE(image.initialized());
7333
7334     VkBuffer buffer;
7335     VkDeviceMemory mem;
7336     VkMemoryRequirements mem_reqs;
7337
7338     VkBufferCreateInfo buf_info = {};
7339     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7340     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
7341     buf_info.size = 256;
7342     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7343     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
7344     ASSERT_VK_SUCCESS(err);
7345
7346     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
7347
7348     VkMemoryAllocateInfo alloc_info = {};
7349     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7350     alloc_info.allocationSize = 256;
7351     bool pass = false;
7352     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
7353     if (!pass) {
7354         vkDestroyBuffer(m_device->device(), buffer, NULL);
7355         return;
7356     }
7357     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
7358     ASSERT_VK_SUCCESS(err);
7359
7360     // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7362                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
7363     VkBufferImageCopy region = {};
7364     region.bufferRowLength = 128;
7365     region.bufferImageHeight = 128;
7366     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7367
7368     region.imageSubresource.layerCount = 1;
7369     region.imageExtent.height = 4;
7370     region.imageExtent.width = 4;
7371     region.imageExtent.depth = 1;
7372     m_commandBuffer->BeginCommandBuffer();
7373     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7374                            &region);
7375     m_commandBuffer->EndCommandBuffer();
7376
7377     m_errorMonitor->VerifyFound();
7378
7379     vkDestroyBuffer(m_device->device(), buffer, NULL);
7380     vkFreeMemory(m_device->handle(), mem, NULL);
7381 }
7382
7383 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
7384     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7385                      "due to an event dependency being destroyed.");
7386     ASSERT_NO_FATAL_FAILURE(InitState());
7387
7388     VkEvent event;
7389     VkEventCreateInfo evci = {};
7390     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
7391     VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
7392     ASSERT_VK_SUCCESS(result);
7393
7394     m_commandBuffer->BeginCommandBuffer();
7395     vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7396     m_commandBuffer->EndCommandBuffer();
7397
7398     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
7399     // Destroy event dependency prior to submit to cause ERROR
7400     vkDestroyEvent(m_device->device(), event, NULL);
7401
7402     VkSubmitInfo submit_info = {};
7403     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7404     submit_info.commandBufferCount = 1;
7405     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7406     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7407
7408     m_errorMonitor->VerifyFound();
7409 }
7410
7411 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
7412     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7413                      "due to a query pool dependency being destroyed.");
7414     ASSERT_NO_FATAL_FAILURE(InitState());
7415
7416     VkQueryPool query_pool;
7417     VkQueryPoolCreateInfo qpci{};
7418     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7419     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
7420     qpci.queryCount = 1;
7421     VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
7422     ASSERT_VK_SUCCESS(result);
7423
7424     m_commandBuffer->BeginCommandBuffer();
7425     vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
7426     m_commandBuffer->EndCommandBuffer();
7427
7428     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool ");
7429     // Destroy query pool dependency prior to submit to cause ERROR
7430     vkDestroyQueryPool(m_device->device(), query_pool, NULL);
7431
7432     VkSubmitInfo submit_info = {};
7433     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7434     submit_info.commandBufferCount = 1;
7435     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7436     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7437
7438     m_errorMonitor->VerifyFound();
7439 }
7440
7441 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
7442     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7443                      "due to a pipeline dependency being destroyed.");
7444     ASSERT_NO_FATAL_FAILURE(InitState());
7445     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7446
7447     VkResult err;
7448
7449     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7450     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7451
7452     VkPipelineLayout pipeline_layout;
7453     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7454     ASSERT_VK_SUCCESS(err);
7455
7456     VkPipelineViewportStateCreateInfo vp_state_ci = {};
7457     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7458     vp_state_ci.viewportCount = 1;
7459     VkViewport vp = {}; // Just need dummy vp to point to
7460     vp_state_ci.pViewports = &vp;
7461     vp_state_ci.scissorCount = 1;
7462     VkRect2D scissors = {}; // Dummy scissors to point to
7463     vp_state_ci.pScissors = &scissors;
7464
7465     VkPipelineShaderStageCreateInfo shaderStages[2];
7466     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
7467
7468     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7469     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
7470     // but add it to be able to run on more devices
7471     shaderStages[0] = vs.GetStageCreateInfo();
7472     shaderStages[1] = fs.GetStageCreateInfo();
7473
7474     VkPipelineVertexInputStateCreateInfo vi_ci = {};
7475     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7476
7477     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
7478     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7479     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
7480
7481     VkPipelineRasterizationStateCreateInfo rs_ci = {};
7482     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7483     rs_ci.rasterizerDiscardEnable = true;
7484     rs_ci.lineWidth = 1.0f;
7485
7486     VkPipelineColorBlendAttachmentState att = {};
7487     att.blendEnable = VK_FALSE;
7488     att.colorWriteMask = 0xf;
7489
7490     VkPipelineColorBlendStateCreateInfo cb_ci = {};
7491     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7492     cb_ci.attachmentCount = 1;
7493     cb_ci.pAttachments = &att;
7494
7495     VkGraphicsPipelineCreateInfo gp_ci = {};
7496     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7497     gp_ci.stageCount = 2;
7498     gp_ci.pStages = shaderStages;
7499     gp_ci.pVertexInputState = &vi_ci;
7500     gp_ci.pInputAssemblyState = &ia_ci;
7501     gp_ci.pViewportState = &vp_state_ci;
7502     gp_ci.pRasterizationState = &rs_ci;
7503     gp_ci.pColorBlendState = &cb_ci;
7504     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
7505     gp_ci.layout = pipeline_layout;
7506     gp_ci.renderPass = renderPass();
7507
7508     VkPipelineCacheCreateInfo pc_ci = {};
7509     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
7510
7511     VkPipeline pipeline;
7512     VkPipelineCache pipelineCache;
7513     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
7514     ASSERT_VK_SUCCESS(err);
7515
7516     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
7517     ASSERT_VK_SUCCESS(err);
7518
7519     m_commandBuffer->BeginCommandBuffer();
7520     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
7521     m_commandBuffer->EndCommandBuffer();
7522     // Now destroy pipeline in order to cause error when submitting
7523     vkDestroyPipeline(m_device->device(), pipeline, nullptr);
7524
7525     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline ");
7526
7527     VkSubmitInfo submit_info = {};
7528     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7529     submit_info.commandBufferCount = 1;
7530     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7531     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7532
7533     m_errorMonitor->VerifyFound();
7534     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
7535     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7536 }
7537
7538 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
7539     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7540                      "due to a bound descriptor set with a buffer dependency "
7541                      "being destroyed.");
7542     ASSERT_NO_FATAL_FAILURE(InitState());
7543     ASSERT_NO_FATAL_FAILURE(InitViewport());
7544     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7545
7546     VkDescriptorPoolSize ds_type_count = {};
7547     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7548     ds_type_count.descriptorCount = 1;
7549
7550     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7551     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7552     ds_pool_ci.pNext = NULL;
7553     ds_pool_ci.maxSets = 1;
7554     ds_pool_ci.poolSizeCount = 1;
7555     ds_pool_ci.pPoolSizes = &ds_type_count;
7556
7557     VkDescriptorPool ds_pool;
7558     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7559     ASSERT_VK_SUCCESS(err);
7560
7561     VkDescriptorSetLayoutBinding dsl_binding = {};
7562     dsl_binding.binding = 0;
7563     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7564     dsl_binding.descriptorCount = 1;
7565     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7566     dsl_binding.pImmutableSamplers = NULL;
7567
7568     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7569     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7570     ds_layout_ci.pNext = NULL;
7571     ds_layout_ci.bindingCount = 1;
7572     ds_layout_ci.pBindings = &dsl_binding;
7573     VkDescriptorSetLayout ds_layout;
7574     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7575     ASSERT_VK_SUCCESS(err);
7576
7577     VkDescriptorSet descriptorSet;
7578     VkDescriptorSetAllocateInfo alloc_info = {};
7579     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7580     alloc_info.descriptorSetCount = 1;
7581     alloc_info.descriptorPool = ds_pool;
7582     alloc_info.pSetLayouts = &ds_layout;
7583     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7584     ASSERT_VK_SUCCESS(err);
7585
7586     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7587     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7588     pipeline_layout_ci.pNext = NULL;
7589     pipeline_layout_ci.setLayoutCount = 1;
7590     pipeline_layout_ci.pSetLayouts = &ds_layout;
7591
7592     VkPipelineLayout pipeline_layout;
7593     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7594     ASSERT_VK_SUCCESS(err);
7595
7596     // Create a buffer to update the descriptor with
7597     uint32_t qfi = 0;
7598     VkBufferCreateInfo buffCI = {};
7599     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7600     buffCI.size = 1024;
7601     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
7602     buffCI.queueFamilyIndexCount = 1;
7603     buffCI.pQueueFamilyIndices = &qfi;
7604
7605     VkBuffer buffer;
7606     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
7607     ASSERT_VK_SUCCESS(err);
7608     // Allocate memory and bind to buffer so we can make it to the appropriate
7609     // error
7610     VkMemoryAllocateInfo mem_alloc = {};
7611     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7612     mem_alloc.pNext = NULL;
7613     mem_alloc.allocationSize = 1024;
7614     mem_alloc.memoryTypeIndex = 0;
7615
7616     VkMemoryRequirements memReqs;
7617     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
7618     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
7619     if (!pass) {
7620         vkDestroyBuffer(m_device->device(), buffer, NULL);
7621         return;
7622     }
7623
7624     VkDeviceMemory mem;
7625     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
7626     ASSERT_VK_SUCCESS(err);
7627     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7628     ASSERT_VK_SUCCESS(err);
7629     // Correctly update descriptor to avoid "NOT_UPDATED" error
7630     VkDescriptorBufferInfo buffInfo = {};
7631     buffInfo.buffer = buffer;
7632     buffInfo.offset = 0;
7633     buffInfo.range = 1024;
7634
7635     VkWriteDescriptorSet descriptor_write;
7636     memset(&descriptor_write, 0, sizeof(descriptor_write));
7637     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7638     descriptor_write.dstSet = descriptorSet;
7639     descriptor_write.dstBinding = 0;
7640     descriptor_write.descriptorCount = 1;
7641     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7642     descriptor_write.pBufferInfo = &buffInfo;
7643
7644     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7645
7646     // Create PSO to be used for draw-time errors below
7647     char const *vsSource = "#version 450\n"
7648                            "\n"
7649                            "out gl_PerVertex { \n"
7650                            "    vec4 gl_Position;\n"
7651                            "};\n"
7652                            "void main(){\n"
7653                            "   gl_Position = vec4(1);\n"
7654                            "}\n";
7655     char const *fsSource = "#version 450\n"
7656                            "\n"
7657                            "layout(location=0) out vec4 x;\n"
7658                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
7659                            "void main(){\n"
7660                            "   x = vec4(bar.y);\n"
7661                            "}\n";
7662     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7663     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7664     VkPipelineObj pipe(m_device);
7665     pipe.AddShader(&vs);
7666     pipe.AddShader(&fs);
7667     pipe.AddColorAttachment();
7668     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7669
7670     BeginCommandBuffer();
7671     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7672     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7673                             &descriptorSet, 0, NULL);
7674     Draw(1, 0, 0, 0);
7675     EndCommandBuffer();
7676     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
7677     // Destroy buffer should invalidate the cmd buffer, causing error on submit
7678     vkDestroyBuffer(m_device->device(), buffer, NULL);
7679     // Attempt to submit cmd buffer
7680     VkSubmitInfo submit_info = {};
7681     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7682     submit_info.commandBufferCount = 1;
7683     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7684     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7685     m_errorMonitor->VerifyFound();
7686     // Cleanup
7687     vkFreeMemory(m_device->device(), mem, NULL);
7688
7689     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7690     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7691     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7692 }
7693
7694 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
7695     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7696                      "due to a bound descriptor sets with a combined image "
7697                      "sampler having their image, sampler, and descriptor set "
7698                      "each respectively destroyed and then attempting to "
7699                      "submit associated cmd buffers. Attempt to destroy a "
7700                      "DescriptorSet that is in use.");
7701     ASSERT_NO_FATAL_FAILURE(InitState());
7702     ASSERT_NO_FATAL_FAILURE(InitViewport());
7703     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7704
7705     VkDescriptorPoolSize ds_type_count = {};
7706     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7707     ds_type_count.descriptorCount = 1;
7708
7709     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7710     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7711     ds_pool_ci.pNext = NULL;
7712     ds_pool_ci.maxSets = 1;
7713     ds_pool_ci.poolSizeCount = 1;
7714     ds_pool_ci.pPoolSizes = &ds_type_count;
7715
7716     VkDescriptorPool ds_pool;
7717     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7718     ASSERT_VK_SUCCESS(err);
7719
7720     VkDescriptorSetLayoutBinding dsl_binding = {};
7721     dsl_binding.binding = 0;
7722     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7723     dsl_binding.descriptorCount = 1;
7724     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7725     dsl_binding.pImmutableSamplers = NULL;
7726
7727     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7728     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7729     ds_layout_ci.pNext = NULL;
7730     ds_layout_ci.bindingCount = 1;
7731     ds_layout_ci.pBindings = &dsl_binding;
7732     VkDescriptorSetLayout ds_layout;
7733     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7734     ASSERT_VK_SUCCESS(err);
7735
7736     VkDescriptorSet descriptorSet;
7737     VkDescriptorSetAllocateInfo alloc_info = {};
7738     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7739     alloc_info.descriptorSetCount = 1;
7740     alloc_info.descriptorPool = ds_pool;
7741     alloc_info.pSetLayouts = &ds_layout;
7742     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7743     ASSERT_VK_SUCCESS(err);
7744
7745     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7746     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7747     pipeline_layout_ci.pNext = NULL;
7748     pipeline_layout_ci.setLayoutCount = 1;
7749     pipeline_layout_ci.pSetLayouts = &ds_layout;
7750
7751     VkPipelineLayout pipeline_layout;
7752     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7753     ASSERT_VK_SUCCESS(err);
7754
7755     // Create images to update the descriptor with
7756     VkImage image;
7757     VkImage image2;
7758     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7759     const int32_t tex_width = 32;
7760     const int32_t tex_height = 32;
7761     VkImageCreateInfo image_create_info = {};
7762     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7763     image_create_info.pNext = NULL;
7764     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7765     image_create_info.format = tex_format;
7766     image_create_info.extent.width = tex_width;
7767     image_create_info.extent.height = tex_height;
7768     image_create_info.extent.depth = 1;
7769     image_create_info.mipLevels = 1;
7770     image_create_info.arrayLayers = 1;
7771     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7772     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7773     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
7774     image_create_info.flags = 0;
7775     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7776     ASSERT_VK_SUCCESS(err);
7777     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
7778     ASSERT_VK_SUCCESS(err);
7779
7780     VkMemoryRequirements memory_reqs;
7781     VkDeviceMemory image_memory;
7782     bool pass;
7783     VkMemoryAllocateInfo memory_info = {};
7784     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7785     memory_info.pNext = NULL;
7786     memory_info.allocationSize = 0;
7787     memory_info.memoryTypeIndex = 0;
7788     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7789     // Allocate enough memory for both images
7790     memory_info.allocationSize = memory_reqs.size * 2;
7791     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7792     ASSERT_TRUE(pass);
7793     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7794     ASSERT_VK_SUCCESS(err);
7795     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7796     ASSERT_VK_SUCCESS(err);
7797     // Bind second image to memory right after first image
7798     err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
7799     ASSERT_VK_SUCCESS(err);
7800
7801     VkImageViewCreateInfo image_view_create_info = {};
7802     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7803     image_view_create_info.image = image;
7804     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
7805     image_view_create_info.format = tex_format;
7806     image_view_create_info.subresourceRange.layerCount = 1;
7807     image_view_create_info.subresourceRange.baseMipLevel = 0;
7808     image_view_create_info.subresourceRange.levelCount = 1;
7809     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7810
7811     VkImageView view;
7812     VkImageView view2;
7813     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
7814     ASSERT_VK_SUCCESS(err);
7815     image_view_create_info.image = image2;
7816     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
7817     ASSERT_VK_SUCCESS(err);
7818     // Create Samplers
7819     VkSamplerCreateInfo sampler_ci = {};
7820     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
7821     sampler_ci.pNext = NULL;
7822     sampler_ci.magFilter = VK_FILTER_NEAREST;
7823     sampler_ci.minFilter = VK_FILTER_NEAREST;
7824     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
7825     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7826     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7827     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7828     sampler_ci.mipLodBias = 1.0;
7829     sampler_ci.anisotropyEnable = VK_FALSE;
7830     sampler_ci.maxAnisotropy = 1;
7831     sampler_ci.compareEnable = VK_FALSE;
7832     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
7833     sampler_ci.minLod = 1.0;
7834     sampler_ci.maxLod = 1.0;
7835     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
7836     sampler_ci.unnormalizedCoordinates = VK_FALSE;
7837     VkSampler sampler;
7838     VkSampler sampler2;
7839     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7840     ASSERT_VK_SUCCESS(err);
7841     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
7842     ASSERT_VK_SUCCESS(err);
7843     // Update descriptor with image and sampler
7844     VkDescriptorImageInfo img_info = {};
7845     img_info.sampler = sampler;
7846     img_info.imageView = view;
7847     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7848
7849     VkWriteDescriptorSet descriptor_write;
7850     memset(&descriptor_write, 0, sizeof(descriptor_write));
7851     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7852     descriptor_write.dstSet = descriptorSet;
7853     descriptor_write.dstBinding = 0;
7854     descriptor_write.descriptorCount = 1;
7855     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7856     descriptor_write.pImageInfo = &img_info;
7857
7858     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7859
7860     // Create PSO to be used for draw-time errors below
7861     char const *vsSource = "#version 450\n"
7862                            "\n"
7863                            "out gl_PerVertex { \n"
7864                            "    vec4 gl_Position;\n"
7865                            "};\n"
7866                            "void main(){\n"
7867                            "   gl_Position = vec4(1);\n"
7868                            "}\n";
7869     char const *fsSource = "#version 450\n"
7870                            "\n"
7871                            "layout(set=0, binding=0) uniform sampler2D s;\n"
7872                            "layout(location=0) out vec4 x;\n"
7873                            "void main(){\n"
7874                            "   x = texture(s, vec2(1));\n"
7875                            "}\n";
7876     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7877     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7878     VkPipelineObj pipe(m_device);
7879     pipe.AddShader(&vs);
7880     pipe.AddShader(&fs);
7881     pipe.AddColorAttachment();
7882     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7883
7884     // First error case is destroying sampler prior to cmd buffer submission
7885     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler ");
7886     BeginCommandBuffer();
7887     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7888     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7889                             &descriptorSet, 0, NULL);
7890     Draw(1, 0, 0, 0);
7891     EndCommandBuffer();
7892     // Destroy sampler invalidates the cmd buffer, causing error on submit
7893     vkDestroySampler(m_device->device(), sampler, NULL);
7894     // Attempt to submit cmd buffer
7895     VkSubmitInfo submit_info = {};
7896     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7897     submit_info.commandBufferCount = 1;
7898     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7899     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7900     m_errorMonitor->VerifyFound();
7901     // Now re-update descriptor with valid sampler and delete image
7902     img_info.sampler = sampler2;
7903     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7904     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7905     BeginCommandBuffer();
7906     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7907     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7908                             &descriptorSet, 0, NULL);
7909     Draw(1, 0, 0, 0);
7910     EndCommandBuffer();
7911     // Destroy image invalidates the cmd buffer, causing error on submit
7912     vkDestroyImage(m_device->device(), image, NULL);
7913     // Attempt to submit cmd buffer
7914     submit_info = {};
7915     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7916     submit_info.commandBufferCount = 1;
7917     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7918     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7919     m_errorMonitor->VerifyFound();
7920     // Now update descriptor to be valid, but then free descriptor
7921     img_info.imageView = view2;
7922     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set ");
7924     BeginCommandBuffer();
7925     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7926     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7927                             &descriptorSet, 0, NULL);
7928     Draw(1, 0, 0, 0);
7929     EndCommandBuffer();
7930     // Destroy descriptor set invalidates the cb, causing error on submit
7931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
7932     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
7933     m_errorMonitor->VerifyFound();
7934     // Attempt to submit cmd buffer
7935     submit_info = {};
7936     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7937     submit_info.commandBufferCount = 1;
7938     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7939     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7940     m_errorMonitor->VerifyFound();
7941     // Cleanup
7942     vkFreeMemory(m_device->device(), image_memory, NULL);
7943     vkDestroySampler(m_device->device(), sampler2, NULL);
7944     vkDestroyImage(m_device->device(), image2, NULL);
7945     vkDestroyImageView(m_device->device(), view, NULL);
7946     vkDestroyImageView(m_device->device(), view2, NULL);
7947     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7948     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7949     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7950 }
7951
7952 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
7953     TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
7954     ASSERT_NO_FATAL_FAILURE(InitState());
7955     ASSERT_NO_FATAL_FAILURE(InitViewport());
7956     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7957
7958     VkDescriptorPoolSize ds_type_count = {};
7959     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7960     ds_type_count.descriptorCount = 1;
7961
7962     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7963     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7964     ds_pool_ci.pNext = NULL;
7965     ds_pool_ci.maxSets = 1;
7966     ds_pool_ci.poolSizeCount = 1;
7967     ds_pool_ci.pPoolSizes = &ds_type_count;
7968
7969     VkDescriptorPool ds_pool;
7970     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7971     ASSERT_VK_SUCCESS(err);
7972
7973     VkDescriptorSetLayoutBinding dsl_binding = {};
7974     dsl_binding.binding = 0;
7975     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7976     dsl_binding.descriptorCount = 1;
7977     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7978     dsl_binding.pImmutableSamplers = NULL;
7979
7980     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7981     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7982     ds_layout_ci.pNext = NULL;
7983     ds_layout_ci.bindingCount = 1;
7984     ds_layout_ci.pBindings = &dsl_binding;
7985     VkDescriptorSetLayout ds_layout;
7986     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7987     ASSERT_VK_SUCCESS(err);
7988
7989     VkDescriptorSet descriptorSet;
7990     VkDescriptorSetAllocateInfo alloc_info = {};
7991     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7992     alloc_info.descriptorSetCount = 1;
7993     alloc_info.descriptorPool = ds_pool;
7994     alloc_info.pSetLayouts = &ds_layout;
7995     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7996     ASSERT_VK_SUCCESS(err);
7997
7998     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7999     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8000     pipeline_layout_ci.pNext = NULL;
8001     pipeline_layout_ci.setLayoutCount = 1;
8002     pipeline_layout_ci.pSetLayouts = &ds_layout;
8003
8004     VkPipelineLayout pipeline_layout;
8005     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8006     ASSERT_VK_SUCCESS(err);
8007
8008     // Create images to update the descriptor with
8009     VkImage image;
8010     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8011     const int32_t tex_width = 32;
8012     const int32_t tex_height = 32;
8013     VkImageCreateInfo image_create_info = {};
8014     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8015     image_create_info.pNext = NULL;
8016     image_create_info.imageType = VK_IMAGE_TYPE_2D;
8017     image_create_info.format = tex_format;
8018     image_create_info.extent.width = tex_width;
8019     image_create_info.extent.height = tex_height;
8020     image_create_info.extent.depth = 1;
8021     image_create_info.mipLevels = 1;
8022     image_create_info.arrayLayers = 1;
8023     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
8024     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
8025     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8026     image_create_info.flags = 0;
8027     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
8028     ASSERT_VK_SUCCESS(err);
8029     // Initially bind memory to avoid error at bind view time. We'll break binding before update.
8030     VkMemoryRequirements memory_reqs;
8031     VkDeviceMemory image_memory;
8032     bool pass;
8033     VkMemoryAllocateInfo memory_info = {};
8034     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8035     memory_info.pNext = NULL;
8036     memory_info.allocationSize = 0;
8037     memory_info.memoryTypeIndex = 0;
8038     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
8039     // Allocate enough memory for image
8040     memory_info.allocationSize = memory_reqs.size;
8041     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
8042     ASSERT_TRUE(pass);
8043     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
8044     ASSERT_VK_SUCCESS(err);
8045     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
8046     ASSERT_VK_SUCCESS(err);
8047
8048     VkImageViewCreateInfo image_view_create_info = {};
8049     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8050     image_view_create_info.image = image;
8051     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
8052     image_view_create_info.format = tex_format;
8053     image_view_create_info.subresourceRange.layerCount = 1;
8054     image_view_create_info.subresourceRange.baseMipLevel = 0;
8055     image_view_create_info.subresourceRange.levelCount = 1;
8056     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8057
8058     VkImageView view;
8059     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
8060     ASSERT_VK_SUCCESS(err);
8061     // Create Samplers
8062     VkSamplerCreateInfo sampler_ci = {};
8063     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
8064     sampler_ci.pNext = NULL;
8065     sampler_ci.magFilter = VK_FILTER_NEAREST;
8066     sampler_ci.minFilter = VK_FILTER_NEAREST;
8067     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
8068     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8069     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8070     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8071     sampler_ci.mipLodBias = 1.0;
8072     sampler_ci.anisotropyEnable = VK_FALSE;
8073     sampler_ci.maxAnisotropy = 1;
8074     sampler_ci.compareEnable = VK_FALSE;
8075     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
8076     sampler_ci.minLod = 1.0;
8077     sampler_ci.maxLod = 1.0;
8078     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
8079     sampler_ci.unnormalizedCoordinates = VK_FALSE;
8080     VkSampler sampler;
8081     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8082     ASSERT_VK_SUCCESS(err);
8083     // Update descriptor with image and sampler
8084     VkDescriptorImageInfo img_info = {};
8085     img_info.sampler = sampler;
8086     img_info.imageView = view;
8087     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8088
8089     VkWriteDescriptorSet descriptor_write;
8090     memset(&descriptor_write, 0, sizeof(descriptor_write));
8091     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8092     descriptor_write.dstSet = descriptorSet;
8093     descriptor_write.dstBinding = 0;
8094     descriptor_write.descriptorCount = 1;
8095     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8096     descriptor_write.pImageInfo = &img_info;
8097     // Break memory binding and attempt update
8098     vkFreeMemory(m_device->device(), image_memory, nullptr);
8099     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8100                                          " previously bound memory was freed. Memory must not be freed prior to this operation.");
8101     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8102                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8103     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8104     m_errorMonitor->VerifyFound();
8105     // Cleanup
8106     vkDestroyImage(m_device->device(), image, NULL);
8107     vkDestroySampler(m_device->device(), sampler, NULL);
8108     vkDestroyImageView(m_device->device(), view, NULL);
8109     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8110     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8111     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8112 }
8113
8114 TEST_F(VkLayerTest, InvalidPipeline) {
8115     // Attempt to bind an invalid Pipeline to a valid Command Buffer
8116     // ObjectTracker should catch this.
8117     // Create a valid cmd buffer
8118     // call vkCmdBindPipeline w/ false Pipeline
8119     uint64_t fake_pipeline_handle = 0xbaad6001;
8120     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
8121     ASSERT_NO_FATAL_FAILURE(InitState());
8122     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8123
8124     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
8125     BeginCommandBuffer();
8126     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
8127     m_errorMonitor->VerifyFound();
8128
8129     // Now issue a draw call with no pipeline bound
8130     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8131     Draw(1, 0, 0, 0);
8132     m_errorMonitor->VerifyFound();
8133
8134     // Finally same check once more but with Dispatch/Compute
8135     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8136     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
8137     vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
8138     m_errorMonitor->VerifyFound();
8139 }
8140
8141 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
8142     TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
8143     VkResult err;
8144
8145     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
8146
8147     ASSERT_NO_FATAL_FAILURE(InitState());
8148     ASSERT_NO_FATAL_FAILURE(InitViewport());
8149     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8150     VkDescriptorPoolSize ds_type_count = {};
8151     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8152     ds_type_count.descriptorCount = 1;
8153
8154     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8155     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8156     ds_pool_ci.pNext = NULL;
8157     ds_pool_ci.maxSets = 1;
8158     ds_pool_ci.poolSizeCount = 1;
8159     ds_pool_ci.pPoolSizes = &ds_type_count;
8160
8161     VkDescriptorPool ds_pool;
8162     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8163     ASSERT_VK_SUCCESS(err);
8164
8165     VkDescriptorSetLayoutBinding dsl_binding = {};
8166     dsl_binding.binding = 0;
8167     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8168     dsl_binding.descriptorCount = 1;
8169     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8170     dsl_binding.pImmutableSamplers = NULL;
8171
8172     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8173     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8174     ds_layout_ci.pNext = NULL;
8175     ds_layout_ci.bindingCount = 1;
8176     ds_layout_ci.pBindings = &dsl_binding;
8177     VkDescriptorSetLayout ds_layout;
8178     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8179     ASSERT_VK_SUCCESS(err);
8180
8181     VkDescriptorSet descriptorSet;
8182     VkDescriptorSetAllocateInfo alloc_info = {};
8183     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8184     alloc_info.descriptorSetCount = 1;
8185     alloc_info.descriptorPool = ds_pool;
8186     alloc_info.pSetLayouts = &ds_layout;
8187     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8188     ASSERT_VK_SUCCESS(err);
8189
8190     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8191     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8192     pipeline_layout_ci.pNext = NULL;
8193     pipeline_layout_ci.setLayoutCount = 1;
8194     pipeline_layout_ci.pSetLayouts = &ds_layout;
8195
8196     VkPipelineLayout pipeline_layout;
8197     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8198     ASSERT_VK_SUCCESS(err);
8199
8200     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8201     //  We shouldn't need a fragment shader but add it to be able to run
8202     //  on more devices
8203     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8204
8205     VkPipelineObj pipe(m_device);
8206     pipe.AddShader(&vs);
8207     pipe.AddShader(&fs);
8208     pipe.AddColorAttachment();
8209     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8210
8211     BeginCommandBuffer();
8212     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8213     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8214                             &descriptorSet, 0, NULL);
8215
8216     m_errorMonitor->VerifyFound();
8217
8218     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8219     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8220     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8221 }
8222
8223 TEST_F(VkLayerTest, InvalidBufferViewObject) {
8224     // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
8225     VkResult err;
8226
8227     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer "
8228                                                                         "descriptor with invalid buffer view");
8229
8230     ASSERT_NO_FATAL_FAILURE(InitState());
8231     VkDescriptorPoolSize ds_type_count = {};
8232     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8233     ds_type_count.descriptorCount = 1;
8234
8235     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8236     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8237     ds_pool_ci.pNext = NULL;
8238     ds_pool_ci.maxSets = 1;
8239     ds_pool_ci.poolSizeCount = 1;
8240     ds_pool_ci.pPoolSizes = &ds_type_count;
8241
8242     VkDescriptorPool ds_pool;
8243     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8244     ASSERT_VK_SUCCESS(err);
8245
8246     VkDescriptorSetLayoutBinding dsl_binding = {};
8247     dsl_binding.binding = 0;
8248     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8249     dsl_binding.descriptorCount = 1;
8250     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8251     dsl_binding.pImmutableSamplers = NULL;
8252
8253     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8254     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8255     ds_layout_ci.pNext = NULL;
8256     ds_layout_ci.bindingCount = 1;
8257     ds_layout_ci.pBindings = &dsl_binding;
8258     VkDescriptorSetLayout ds_layout;
8259     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8260     ASSERT_VK_SUCCESS(err);
8261
8262     VkDescriptorSet descriptorSet;
8263     VkDescriptorSetAllocateInfo alloc_info = {};
8264     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8265     alloc_info.descriptorSetCount = 1;
8266     alloc_info.descriptorPool = ds_pool;
8267     alloc_info.pSetLayouts = &ds_layout;
8268     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8269     ASSERT_VK_SUCCESS(err);
8270
8271     VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object
8272     VkWriteDescriptorSet descriptor_write;
8273     memset(&descriptor_write, 0, sizeof(descriptor_write));
8274     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8275     descriptor_write.dstSet = descriptorSet;
8276     descriptor_write.dstBinding = 0;
8277     descriptor_write.descriptorCount = 1;
8278     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8279     descriptor_write.pTexelBufferView = &view;
8280
8281     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8282
8283     m_errorMonitor->VerifyFound();
8284
8285     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8286     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8287 }
8288
8289 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
8290     TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
8291
8292     VkResult err;
8293     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8294                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8295
8296     ASSERT_NO_FATAL_FAILURE(InitState());
8297
8298     // Create a buffer with no bound memory and then attempt to create
8299     // a buffer view.
8300     VkBufferCreateInfo buff_ci = {};
8301     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8302     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
8303     buff_ci.size = 256;
8304     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8305     VkBuffer buffer;
8306     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
8307     ASSERT_VK_SUCCESS(err);
8308
8309     VkBufferViewCreateInfo buff_view_ci = {};
8310     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8311     buff_view_ci.buffer = buffer;
8312     buff_view_ci.format = VK_FORMAT_R8_UNORM;
8313     buff_view_ci.range = VK_WHOLE_SIZE;
8314     VkBufferView buff_view;
8315     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
8316
8317     m_errorMonitor->VerifyFound();
8318     vkDestroyBuffer(m_device->device(), buffer, NULL);
8319     // If last error is success, it still created the view, so delete it.
8320     if (err == VK_SUCCESS) {
8321         vkDestroyBufferView(m_device->device(), buff_view, NULL);
8322     }
8323 }
8324
8325 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
8326     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
8327     // cases:
8328     // 1. No dynamicOffset supplied
8329     // 2. Too many dynamicOffsets supplied
8330     // 3. Dynamic offset oversteps buffer being updated
8331     VkResult err;
8332     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only "
8333                                                                         "0 dynamicOffsets are left in "
8334                                                                         "pDynamicOffsets ");
8335
8336     ASSERT_NO_FATAL_FAILURE(InitState());
8337     ASSERT_NO_FATAL_FAILURE(InitViewport());
8338     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8339
8340     VkDescriptorPoolSize ds_type_count = {};
8341     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8342     ds_type_count.descriptorCount = 1;
8343
8344     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8345     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8346     ds_pool_ci.pNext = NULL;
8347     ds_pool_ci.maxSets = 1;
8348     ds_pool_ci.poolSizeCount = 1;
8349     ds_pool_ci.pPoolSizes = &ds_type_count;
8350
8351     VkDescriptorPool ds_pool;
8352     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8353     ASSERT_VK_SUCCESS(err);
8354
8355     VkDescriptorSetLayoutBinding dsl_binding = {};
8356     dsl_binding.binding = 0;
8357     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8358     dsl_binding.descriptorCount = 1;
8359     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8360     dsl_binding.pImmutableSamplers = NULL;
8361
8362     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8363     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8364     ds_layout_ci.pNext = NULL;
8365     ds_layout_ci.bindingCount = 1;
8366     ds_layout_ci.pBindings = &dsl_binding;
8367     VkDescriptorSetLayout ds_layout;
8368     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8369     ASSERT_VK_SUCCESS(err);
8370
8371     VkDescriptorSet descriptorSet;
8372     VkDescriptorSetAllocateInfo alloc_info = {};
8373     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8374     alloc_info.descriptorSetCount = 1;
8375     alloc_info.descriptorPool = ds_pool;
8376     alloc_info.pSetLayouts = &ds_layout;
8377     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8378     ASSERT_VK_SUCCESS(err);
8379
8380     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8381     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8382     pipeline_layout_ci.pNext = NULL;
8383     pipeline_layout_ci.setLayoutCount = 1;
8384     pipeline_layout_ci.pSetLayouts = &ds_layout;
8385
8386     VkPipelineLayout pipeline_layout;
8387     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8388     ASSERT_VK_SUCCESS(err);
8389
8390     // Create a buffer to update the descriptor with
8391     uint32_t qfi = 0;
8392     VkBufferCreateInfo buffCI = {};
8393     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8394     buffCI.size = 1024;
8395     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8396     buffCI.queueFamilyIndexCount = 1;
8397     buffCI.pQueueFamilyIndices = &qfi;
8398
8399     VkBuffer dyub;
8400     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8401     ASSERT_VK_SUCCESS(err);
8402     // Allocate memory and bind to buffer so we can make it to the appropriate
8403     // error
8404     VkMemoryAllocateInfo mem_alloc = {};
8405     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8406     mem_alloc.pNext = NULL;
8407     mem_alloc.allocationSize = 1024;
8408     mem_alloc.memoryTypeIndex = 0;
8409
8410     VkMemoryRequirements memReqs;
8411     vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
8412     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
8413     if (!pass) {
8414         vkDestroyBuffer(m_device->device(), dyub, NULL);
8415         return;
8416     }
8417
8418     VkDeviceMemory mem;
8419     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
8420     ASSERT_VK_SUCCESS(err);
8421     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8422     ASSERT_VK_SUCCESS(err);
8423     // Correctly update descriptor to avoid "NOT_UPDATED" error
8424     VkDescriptorBufferInfo buffInfo = {};
8425     buffInfo.buffer = dyub;
8426     buffInfo.offset = 0;
8427     buffInfo.range = 1024;
8428
8429     VkWriteDescriptorSet descriptor_write;
8430     memset(&descriptor_write, 0, sizeof(descriptor_write));
8431     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8432     descriptor_write.dstSet = descriptorSet;
8433     descriptor_write.dstBinding = 0;
8434     descriptor_write.descriptorCount = 1;
8435     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8436     descriptor_write.pBufferInfo = &buffInfo;
8437
8438     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8439
8440     BeginCommandBuffer();
8441     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8442                             &descriptorSet, 0, NULL);
8443     m_errorMonitor->VerifyFound();
8444     uint32_t pDynOff[2] = {512, 756};
8445     // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
8446     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8447                                          "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
8448     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8449                             &descriptorSet, 2, pDynOff);
8450     m_errorMonitor->VerifyFound();
8451     // Finally cause error due to dynamicOffset being too big
8452     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with "
8453                                                                         "offset 0 and range 1024 that "
8454                                                                         "oversteps the buffer size of 1024");
8455     // Create PSO to be used for draw-time errors below
8456     char const *vsSource = "#version 450\n"
8457                            "\n"
8458                            "out gl_PerVertex { \n"
8459                            "    vec4 gl_Position;\n"
8460                            "};\n"
8461                            "void main(){\n"
8462                            "   gl_Position = vec4(1);\n"
8463                            "}\n";
8464     char const *fsSource = "#version 450\n"
8465                            "\n"
8466                            "layout(location=0) out vec4 x;\n"
8467                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8468                            "void main(){\n"
8469                            "   x = vec4(bar.y);\n"
8470                            "}\n";
8471     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8472     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8473     VkPipelineObj pipe(m_device);
8474     pipe.AddShader(&vs);
8475     pipe.AddShader(&fs);
8476     pipe.AddColorAttachment();
8477     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8478
8479     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8480     // This update should succeed, but offset size of 512 will overstep buffer
8481     // /w range 1024 & size 1024
8482     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8483                             &descriptorSet, 1, pDynOff);
8484     Draw(1, 0, 0, 0);
8485     m_errorMonitor->VerifyFound();
8486
8487     vkDestroyBuffer(m_device->device(), dyub, NULL);
8488     vkFreeMemory(m_device->device(), mem, NULL);
8489
8490     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8491     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8492     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8493 }
8494
8495 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
8496     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
8497                      "that doesn't have memory bound");
8498     VkResult err;
8499     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8500                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8501     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8502                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8503
8504     ASSERT_NO_FATAL_FAILURE(InitState());
8505     ASSERT_NO_FATAL_FAILURE(InitViewport());
8506     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8507
8508     VkDescriptorPoolSize ds_type_count = {};
8509     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8510     ds_type_count.descriptorCount = 1;
8511
8512     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8513     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8514     ds_pool_ci.pNext = NULL;
8515     ds_pool_ci.maxSets = 1;
8516     ds_pool_ci.poolSizeCount = 1;
8517     ds_pool_ci.pPoolSizes = &ds_type_count;
8518
8519     VkDescriptorPool ds_pool;
8520     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8521     ASSERT_VK_SUCCESS(err);
8522
8523     VkDescriptorSetLayoutBinding dsl_binding = {};
8524     dsl_binding.binding = 0;
8525     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8526     dsl_binding.descriptorCount = 1;
8527     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8528     dsl_binding.pImmutableSamplers = NULL;
8529
8530     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8531     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8532     ds_layout_ci.pNext = NULL;
8533     ds_layout_ci.bindingCount = 1;
8534     ds_layout_ci.pBindings = &dsl_binding;
8535     VkDescriptorSetLayout ds_layout;
8536     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8537     ASSERT_VK_SUCCESS(err);
8538
8539     VkDescriptorSet descriptorSet;
8540     VkDescriptorSetAllocateInfo alloc_info = {};
8541     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8542     alloc_info.descriptorSetCount = 1;
8543     alloc_info.descriptorPool = ds_pool;
8544     alloc_info.pSetLayouts = &ds_layout;
8545     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8546     ASSERT_VK_SUCCESS(err);
8547
8548     // Create a buffer to update the descriptor with
8549     uint32_t qfi = 0;
8550     VkBufferCreateInfo buffCI = {};
8551     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8552     buffCI.size = 1024;
8553     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8554     buffCI.queueFamilyIndexCount = 1;
8555     buffCI.pQueueFamilyIndices = &qfi;
8556
8557     VkBuffer dyub;
8558     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8559     ASSERT_VK_SUCCESS(err);
8560
8561     // Attempt to update descriptor without binding memory to it
8562     VkDescriptorBufferInfo buffInfo = {};
8563     buffInfo.buffer = dyub;
8564     buffInfo.offset = 0;
8565     buffInfo.range = 1024;
8566
8567     VkWriteDescriptorSet descriptor_write;
8568     memset(&descriptor_write, 0, sizeof(descriptor_write));
8569     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8570     descriptor_write.dstSet = descriptorSet;
8571     descriptor_write.dstBinding = 0;
8572     descriptor_write.descriptorCount = 1;
8573     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8574     descriptor_write.pBufferInfo = &buffInfo;
8575
8576     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8577     m_errorMonitor->VerifyFound();
8578
8579     vkDestroyBuffer(m_device->device(), dyub, NULL);
8580     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8581     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8582 }
8583
8584 TEST_F(VkLayerTest, InvalidPushConstants) {
8585     VkResult err;
8586     ASSERT_NO_FATAL_FAILURE(InitState());
8587     ASSERT_NO_FATAL_FAILURE(InitViewport());
8588     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8589
8590     VkPipelineLayout pipeline_layout;
8591     VkPushConstantRange pc_range = {};
8592     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8593     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8594     pipeline_layout_ci.pushConstantRangeCount = 1;
8595     pipeline_layout_ci.pPushConstantRanges = &pc_range;
8596
8597     //
8598     // Check for invalid push constant ranges in pipeline layouts.
8599     //
8600     struct PipelineLayoutTestCase {
8601         VkPushConstantRange const range;
8602         char const *msg;
8603     };
8604
8605     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
8606     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
8607         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
8608          "vkCreatePipelineLayout() call has push constants index 0 with "
8609          "size 0."},
8610         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8611          "vkCreatePipelineLayout() call has push constants index 0 with "
8612          "size 1."},
8613         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8614          "vkCreatePipelineLayout() call has push constants index 0 with "
8615          "size 1."},
8616         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
8617          "vkCreatePipelineLayout() call has push constants index 0 with "
8618          "size 0."},
8619         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8620          "vkCreatePipelineLayout() call has push constants index 0 with "
8621          "offset 1. Offset must"},
8622         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big},
8623          "vkCreatePipelineLayout() call has push constants index 0 "
8624          "with offset "},
8625         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
8626          "vkCreatePipelineLayout() call has push constants "
8627          "index 0 with offset "},
8628         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
8629          "vkCreatePipelineLayout() call has push constants index 0 "
8630          "with offset "},
8631         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
8632          "vkCreatePipelineLayout() call has push "
8633          "constants index 0 with offset "},
8634         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
8635          "vkCreatePipelineLayout() call has push "
8636          "constants index 0 with offset "},
8637     }};
8638
8639     // Check for invalid offset and size
8640     for (const auto &iter : range_tests) {
8641         pc_range = iter.range;
8642         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8643         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8644         m_errorMonitor->VerifyFound();
8645         if (VK_SUCCESS == err) {
8646             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8647         }
8648     }
8649
8650     // Check for invalid stage flag
8651     pc_range.offset = 0;
8652     pc_range.size = 16;
8653     pc_range.stageFlags = 0;
8654     m_errorMonitor->SetDesiredFailureMsg(
8655         VK_DEBUG_REPORT_ERROR_BIT_EXT,
8656         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
8657     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8658     m_errorMonitor->VerifyFound();
8659     if (VK_SUCCESS == err) {
8660         vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8661     }
8662
8663     // Check for overlapping ranges
8664     const uint32_t ranges_per_test = 5;
8665     struct OverlappingRangeTestCase {
8666         VkPushConstantRange const ranges[ranges_per_test];
8667         char const *msg;
8668     };
8669
8670     const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = {
8671         {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8672            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8673            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8674            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8675            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8676           "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
8677          {
8678              {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8679               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8680               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8681               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8682               {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8683              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
8684          },
8685          {
8686              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8687               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8688               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8689               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8690               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8691              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
8692          },
8693          {
8694              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8695               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8696               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8697               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8698               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8699              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
8700          },
8701          {
8702              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8703               {VK_SHADER_STAGE_VERTEX_BIT, 32, 4},
8704               {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
8705               {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
8706               {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
8707              "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
8708          }}};
8709
8710     for (const auto &iter : overlapping_range_tests) {
8711         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8712         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
8713         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg);
8714         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8715         m_errorMonitor->VerifyFound();
8716         if (VK_SUCCESS == err) {
8717             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8718         }
8719     }
8720
8721     // Run some positive tests to make sure overlap checking in the layer is OK
8722     const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8723                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8724                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8725                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
8726                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8727                                                                                    ""},
8728                                                                                   {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
8729                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
8730                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
8731                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
8732                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8733                                                                                    ""}}};
8734     for (const auto &iter : overlapping_range_tests_pos) {
8735         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8736         m_errorMonitor->ExpectSuccess();
8737         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8738         m_errorMonitor->VerifyNotFound();
8739         if (VK_SUCCESS == err) {
8740             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8741         }
8742     }
8743
8744     //
8745     // CmdPushConstants tests
8746     //
8747     const uint8_t dummy_values[100] = {};
8748
8749     // Check for invalid offset and size and if range is within layout range(s)
8750     const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
8751         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
8752         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8753          "vkCmdPushConstants() call has push constants with size 1. Size "
8754          "must be greater than zero and a multiple of 4."},
8755         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8756          "vkCmdPushConstants() call has push constants with size 1. Size "
8757          "must be greater than zero and a multiple of 4."},
8758         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8759          "vkCmdPushConstants() call has push constants with offset 1. "
8760          "Offset must be a multiple of 4."},
8761         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8762          "vkCmdPushConstants() call has push constants with offset 1. "
8763          "Offset must be a multiple of 4."},
8764         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8765          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8766          "0x1 not within flag-matching ranges in pipeline layout"},
8767         {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8},
8768          "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = "
8769          "0x1 not within flag-matching ranges in pipeline layout"},
8770         {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8},
8771          "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = "
8772          "0x1 not within flag-matching ranges in pipeline layout"},
8773         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80},
8774          "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = "
8775          "0x1 not within flag-matching ranges in pipeline layout"},
8776         {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
8777          "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in "
8778          "any of the ranges in pipeline layout"},
8779         {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
8780          "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
8781          "any of the ranges in pipeline layout"},
8782     }};
8783
8784     BeginCommandBuffer();
8785
8786     // Setup ranges: [0,16) [64,80)
8787     const VkPushConstantRange pc_range2[] = {
8788         {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
8789     };
8790     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange);
8791     pipeline_layout_ci.pPushConstantRanges = pc_range2;
8792     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8793     ASSERT_VK_SUCCESS(err);
8794     for (const auto &iter : cmd_range_tests) {
8795         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8796         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8797                            iter.range.size, dummy_values);
8798         m_errorMonitor->VerifyFound();
8799     }
8800
8801     // Check for invalid stage flag
8802     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
8803     vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
8804     m_errorMonitor->VerifyFound();
8805     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8806
8807     // overlapping range tests with cmd
8808     const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{
8809         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8810          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8811          "0x1 not within flag-matching ranges in pipeline layout"},
8812         {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8813          "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = "
8814          "0x1 not within flag-matching ranges in pipeline layout"},
8815         {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16},
8816          "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
8817          "0x1 not within flag-matching ranges in pipeline layout"},
8818     }};
8819     // Setup ranges:  [0,16), [20,36), [36,44), [44,52), [80,92)
8820     const VkPushConstantRange pc_range3[] = {
8821         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8822         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
8823     };
8824     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
8825     pipeline_layout_ci.pPushConstantRanges = pc_range3;
8826     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8827     ASSERT_VK_SUCCESS(err);
8828     for (const auto &iter : cmd_overlap_tests) {
8829         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8830         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8831                            iter.range.size, dummy_values);
8832         m_errorMonitor->VerifyFound();
8833     }
8834     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8835
8836     // positive overlapping range tests with cmd
8837     const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
8838         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
8839         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
8840         {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
8841         {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
8842     }};
8843     // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
8844     const VkPushConstantRange pc_range4[] = {
8845         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8846         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 24},
8847     };
8848     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
8849     pipeline_layout_ci.pPushConstantRanges = pc_range4;
8850     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8851     ASSERT_VK_SUCCESS(err);
8852     for (const auto &iter : cmd_overlap_tests_pos) {
8853         m_errorMonitor->ExpectSuccess();
8854         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8855                            iter.range.size, dummy_values);
8856         m_errorMonitor->VerifyNotFound();
8857     }
8858     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8859
8860     EndCommandBuffer();
8861 }
8862
8863 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
8864     // Test various desriptorSet errors with bad binding combinations
8865     VkResult err;
8866
8867     ASSERT_NO_FATAL_FAILURE(InitState());
8868     ASSERT_NO_FATAL_FAILURE(InitViewport());
8869     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8870
8871     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
8872     VkImageTiling tiling;
8873     VkFormatProperties format_properties;
8874     vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
8875     if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8876         tiling = VK_IMAGE_TILING_LINEAR;
8877     } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8878         tiling = VK_IMAGE_TILING_OPTIMAL;
8879     } else {
8880         printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
8881                "skipped.\n");
8882         return;
8883     }
8884
8885     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
8886     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
8887     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8888     ds_type_count[0].descriptorCount = 10;
8889     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8890     ds_type_count[1].descriptorCount = 2;
8891     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8892     ds_type_count[2].descriptorCount = 2;
8893     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
8894     ds_type_count[3].descriptorCount = 5;
8895     // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
8896     // type
8897     // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
8898     ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8899     ds_type_count[4].descriptorCount = 2;
8900
8901     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8902     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8903     ds_pool_ci.pNext = NULL;
8904     ds_pool_ci.maxSets = 5;
8905     ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
8906     ds_pool_ci.pPoolSizes = ds_type_count;
8907
8908     VkDescriptorPool ds_pool;
8909     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8910     ASSERT_VK_SUCCESS(err);
8911
8912     static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
8913     VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
8914     dsl_binding[0].binding = 0;
8915     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8916     dsl_binding[0].descriptorCount = 5;
8917     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
8918     dsl_binding[0].pImmutableSamplers = NULL;
8919
8920     // Create layout identical to set0 layout but w/ different stageFlags
8921     VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
8922     dsl_fs_stage_only.binding = 0;
8923     dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8924     dsl_fs_stage_only.descriptorCount = 5;
8925     dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at
8926                                                                  // bind time
8927     dsl_fs_stage_only.pImmutableSamplers = NULL;
8928     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8929     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8930     ds_layout_ci.pNext = NULL;
8931     ds_layout_ci.bindingCount = 1;
8932     ds_layout_ci.pBindings = dsl_binding;
8933     static const uint32_t NUM_LAYOUTS = 4;
8934     VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {};
8935     VkDescriptorSetLayout ds_layout_fs_only = {};
8936     // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
8937     // layout for error case
8938     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]);
8939     ASSERT_VK_SUCCESS(err);
8940     ds_layout_ci.pBindings = &dsl_fs_stage_only;
8941     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only);
8942     ASSERT_VK_SUCCESS(err);
8943     dsl_binding[0].binding = 0;
8944     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8945     dsl_binding[0].descriptorCount = 2;
8946     dsl_binding[1].binding = 1;
8947     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8948     dsl_binding[1].descriptorCount = 2;
8949     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
8950     dsl_binding[1].pImmutableSamplers = NULL;
8951     ds_layout_ci.pBindings = dsl_binding;
8952     ds_layout_ci.bindingCount = 2;
8953     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]);
8954     ASSERT_VK_SUCCESS(err);
8955     dsl_binding[0].binding = 0;
8956     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8957     dsl_binding[0].descriptorCount = 5;
8958     ds_layout_ci.bindingCount = 1;
8959     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]);
8960     ASSERT_VK_SUCCESS(err);
8961     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8962     dsl_binding[0].descriptorCount = 2;
8963     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]);
8964     ASSERT_VK_SUCCESS(err);
8965
8966     static const uint32_t NUM_SETS = 4;
8967     VkDescriptorSet descriptorSet[NUM_SETS] = {};
8968     VkDescriptorSetAllocateInfo alloc_info = {};
8969     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8970     alloc_info.descriptorSetCount = NUM_LAYOUTS;
8971     alloc_info.descriptorPool = ds_pool;
8972     alloc_info.pSetLayouts = ds_layout;
8973     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
8974     ASSERT_VK_SUCCESS(err);
8975     VkDescriptorSet ds0_fs_only = {};
8976     alloc_info.descriptorSetCount = 1;
8977     alloc_info.pSetLayouts = &ds_layout_fs_only;
8978     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
8979     ASSERT_VK_SUCCESS(err);
8980
8981     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8982     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8983     pipeline_layout_ci.pNext = NULL;
8984     pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS;
8985     pipeline_layout_ci.pSetLayouts = ds_layout;
8986
8987     VkPipelineLayout pipeline_layout;
8988     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8989     ASSERT_VK_SUCCESS(err);
8990     // Create pipelineLayout with only one setLayout
8991     pipeline_layout_ci.setLayoutCount = 1;
8992     VkPipelineLayout single_pipe_layout;
8993     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout);
8994     ASSERT_VK_SUCCESS(err);
8995     // Create pipelineLayout with 2 descriptor setLayout at index 0
8996     pipeline_layout_ci.pSetLayouts = &ds_layout[3];
8997     VkPipelineLayout pipe_layout_one_desc;
8998     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc);
8999     ASSERT_VK_SUCCESS(err);
9000     // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
9001     pipeline_layout_ci.pSetLayouts = &ds_layout[2];
9002     VkPipelineLayout pipe_layout_five_samp;
9003     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp);
9004     ASSERT_VK_SUCCESS(err);
9005     // Create pipelineLayout with UB type, but stageFlags for FS only
9006     pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only;
9007     VkPipelineLayout pipe_layout_fs_only;
9008     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only);
9009     ASSERT_VK_SUCCESS(err);
9010     // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
9011     VkDescriptorSetLayout pl_bad_s0[2] = {};
9012     pl_bad_s0[0] = ds_layout_fs_only;
9013     pl_bad_s0[1] = ds_layout[1];
9014     pipeline_layout_ci.setLayoutCount = 2;
9015     pipeline_layout_ci.pSetLayouts = pl_bad_s0;
9016     VkPipelineLayout pipe_layout_bad_set0;
9017     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0);
9018     ASSERT_VK_SUCCESS(err);
9019
9020     // Create a buffer to update the descriptor with
9021     uint32_t qfi = 0;
9022     VkBufferCreateInfo buffCI = {};
9023     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9024     buffCI.size = 1024;
9025     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
9026     buffCI.queueFamilyIndexCount = 1;
9027     buffCI.pQueueFamilyIndices = &qfi;
9028
9029     VkBuffer dyub;
9030     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
9031     ASSERT_VK_SUCCESS(err);
9032     // Correctly update descriptor to avoid "NOT_UPDATED" error
9033     static const uint32_t NUM_BUFFS = 5;
9034     VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {};
9035     for (uint32_t i = 0; i < NUM_BUFFS; ++i) {
9036         buffInfo[i].buffer = dyub;
9037         buffInfo[i].offset = 0;
9038         buffInfo[i].range = 1024;
9039     }
9040     VkImage image;
9041     const int32_t tex_width = 32;
9042     const int32_t tex_height = 32;
9043     VkImageCreateInfo image_create_info = {};
9044     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9045     image_create_info.pNext = NULL;
9046     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9047     image_create_info.format = tex_format;
9048     image_create_info.extent.width = tex_width;
9049     image_create_info.extent.height = tex_height;
9050     image_create_info.extent.depth = 1;
9051     image_create_info.mipLevels = 1;
9052     image_create_info.arrayLayers = 1;
9053     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9054     image_create_info.tiling = tiling;
9055     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
9056     image_create_info.flags = 0;
9057     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9058     ASSERT_VK_SUCCESS(err);
9059
9060     VkMemoryRequirements memReqs;
9061     VkDeviceMemory imageMem;
9062     bool pass;
9063     VkMemoryAllocateInfo memAlloc = {};
9064     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9065     memAlloc.pNext = NULL;
9066     memAlloc.allocationSize = 0;
9067     memAlloc.memoryTypeIndex = 0;
9068     vkGetImageMemoryRequirements(m_device->device(), image, &memReqs);
9069     memAlloc.allocationSize = memReqs.size;
9070     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
9071     ASSERT_TRUE(pass);
9072     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem);
9073     ASSERT_VK_SUCCESS(err);
9074     err = vkBindImageMemory(m_device->device(), image, imageMem, 0);
9075     ASSERT_VK_SUCCESS(err);
9076
9077     VkImageViewCreateInfo image_view_create_info = {};
9078     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
9079     image_view_create_info.image = image;
9080     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
9081     image_view_create_info.format = tex_format;
9082     image_view_create_info.subresourceRange.layerCount = 1;
9083     image_view_create_info.subresourceRange.baseMipLevel = 0;
9084     image_view_create_info.subresourceRange.levelCount = 1;
9085     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9086
9087     VkImageView view;
9088     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
9089     ASSERT_VK_SUCCESS(err);
9090     VkDescriptorImageInfo imageInfo[4] = {};
9091     imageInfo[0].imageView = view;
9092     imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9093     imageInfo[1].imageView = view;
9094     imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9095     imageInfo[2].imageView = view;
9096     imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9097     imageInfo[3].imageView = view;
9098     imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9099
9100     static const uint32_t NUM_SET_UPDATES = 3;
9101     VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
9102     descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9103     descriptor_write[0].dstSet = descriptorSet[0];
9104     descriptor_write[0].dstBinding = 0;
9105     descriptor_write[0].descriptorCount = 5;
9106     descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9107     descriptor_write[0].pBufferInfo = buffInfo;
9108     descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9109     descriptor_write[1].dstSet = descriptorSet[1];
9110     descriptor_write[1].dstBinding = 0;
9111     descriptor_write[1].descriptorCount = 2;
9112     descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9113     descriptor_write[1].pImageInfo = imageInfo;
9114     descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9115     descriptor_write[2].dstSet = descriptorSet[1];
9116     descriptor_write[2].dstBinding = 1;
9117     descriptor_write[2].descriptorCount = 2;
9118     descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9119     descriptor_write[2].pImageInfo = &imageInfo[2];
9120
9121     vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL);
9122
9123     // Create PSO to be used for draw-time errors below
9124     char const *vsSource = "#version 450\n"
9125                            "\n"
9126                            "out gl_PerVertex {\n"
9127                            "    vec4 gl_Position;\n"
9128                            "};\n"
9129                            "void main(){\n"
9130                            "   gl_Position = vec4(1);\n"
9131                            "}\n";
9132     char const *fsSource = "#version 450\n"
9133                            "\n"
9134                            "layout(location=0) out vec4 x;\n"
9135                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
9136                            "void main(){\n"
9137                            "   x = vec4(bar.y);\n"
9138                            "}\n";
9139     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9140     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9141     VkPipelineObj pipe(m_device);
9142     pipe.AddShader(&vs);
9143     pipe.AddShader(&fs);
9144     pipe.AddColorAttachment();
9145     pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass());
9146
9147     BeginCommandBuffer();
9148
9149     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9150     // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
9151     // of PSO
9152     //  here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
9153     //  cmd_pipeline.c
9154     //  due to the fact that cmd_alloc_dset_data() has not been called in
9155     //  cmd_bind_graphics_pipeline()
9156     // TODO : Want to cause various binding incompatibility issues here to test
9157     // DrawState
9158     //  First cause various verify_layout_compatibility() fails
9159     //  Second disturb early and late sets and verify INFO msgs
9160     // verify_set_layout_compatibility fail cases:
9161     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
9162     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object ");
9163     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
9164                             (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL);
9165     m_errorMonitor->VerifyFound();
9166
9167     // 2. layoutIndex exceeds # of layouts in layout
9168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
9169     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2,
9170                             &descriptorSet[0], 0, NULL);
9171     m_errorMonitor->VerifyFound();
9172
9173     vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL);
9174     // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
9175     // descriptors
9176     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
9177     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1,
9178                             &descriptorSet[0], 0, NULL);
9179     m_errorMonitor->VerifyFound();
9180
9181     vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL);
9182     // 4. same # of descriptors but mismatch in type
9183     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
9184     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1,
9185                             &descriptorSet[0], 0, NULL);
9186     m_errorMonitor->VerifyFound();
9187
9188     vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL);
9189     // 5. same # of descriptors but mismatch in stageFlags
9190     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9191                                          " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
9192     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9193                             &descriptorSet[0], 0, NULL);
9194     m_errorMonitor->VerifyFound();
9195
9196     // Cause INFO messages due to disturbing previously bound Sets
9197     // First bind sets 0 & 1
9198     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9199                             &descriptorSet[0], 0, NULL);
9200     // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout
9201     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed ");
9202     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9203                             &descriptorSet[1], 0, NULL);
9204     m_errorMonitor->VerifyFound();
9205
9206     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9207                             &descriptorSet[0], 0, NULL);
9208     // 2. Disturb set after last bound set
9209     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and "
9210                                                                                       "any subsequent sets were disturbed ");
9211     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9212                             &ds0_fs_only, 0, NULL);
9213     m_errorMonitor->VerifyFound();
9214
9215     // Now that we're done actively using the pipelineLayout that gfx pipeline
9216     //  was created with, we should be able to delete it. Do that now to verify
9217     //  that validation obeys pipelineLayout lifetime
9218     vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
9219
9220     // Cause draw-time errors due to PSO incompatibilities
9221     // 1. Error due to not binding required set (we actually use same code as
9222     // above to disturb set0)
9223     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9224                             &descriptorSet[0], 0, NULL);
9225     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9226                             &descriptorSet[1], 0, NULL);
9227     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
9228     Draw(1, 0, 0, 0);
9229     m_errorMonitor->VerifyFound();
9230
9231     vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL);
9232     // 2. Error due to bound set not being compatible with PSO's
9233     // VkPipelineLayout (diff stageFlags in this case)
9234     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9235                             &descriptorSet[0], 0, NULL);
9236     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
9237     Draw(1, 0, 0, 0);
9238     m_errorMonitor->VerifyFound();
9239
9240     // Remaining clean-up
9241     for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
9242         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
9243     }
9244     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
9245     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
9246     vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
9247     vkDestroyBuffer(m_device->device(), dyub, NULL);
9248     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9249     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9250     vkFreeMemory(m_device->device(), imageMem, NULL);
9251     vkDestroyImage(m_device->device(), image, NULL);
9252     vkDestroyImageView(m_device->device(), view, NULL);
9253 }
9254
9255 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
9256
9257     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9258                                          "You must call vkBeginCommandBuffer() before this call to ");
9259
9260     ASSERT_NO_FATAL_FAILURE(InitState());
9261     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9262     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
9263     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9264
9265     m_errorMonitor->VerifyFound();
9266 }
9267
9268 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
9269     VkResult err;
9270     VkCommandBuffer draw_cmd;
9271
9272     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter.");
9273
9274     ASSERT_NO_FATAL_FAILURE(InitState());
9275
9276     VkCommandBufferAllocateInfo cmd = {};
9277     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
9278     cmd.pNext = NULL;
9279     cmd.commandPool = m_commandPool;
9280     cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
9281     cmd.commandBufferCount = 1;
9282
9283     err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd);
9284     ASSERT_VK_SUCCESS(err);
9285
9286     // Force the failure by not setting the Renderpass and Framebuffer fields
9287     VkCommandBufferBeginInfo cmd_buf_info = {};
9288     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9289     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9290     cmd_buf_info.pNext = NULL;
9291     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
9292     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9293
9294     // The error should be caught by validation of the BeginCommandBuffer call
9295     vkBeginCommandBuffer(draw_cmd, &cmd_buf_info);
9296
9297     m_errorMonitor->VerifyFound();
9298     vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd);
9299 }
9300
9301 TEST_F(VkLayerTest, CommandBufferResetErrors) {
9302     // Cause error due to Begin while recording CB
9303     // Then cause 2 errors for attempting to reset CB w/o having
9304     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
9305     // which CBs were allocated. Note that this bit is off by default.
9306     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
9307
9308     ASSERT_NO_FATAL_FAILURE(InitState());
9309
9310     // Calls AllocateCommandBuffers
9311     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9312
9313     // Force the failure by setting the Renderpass and Framebuffer fields with
9314     // (fake) data
9315     VkCommandBufferBeginInfo cmd_buf_info = {};
9316     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9317     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9318     cmd_buf_info.pNext = NULL;
9319     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
9320     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9321
9322     // Begin CB to transition to recording state
9323     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9324     // Can't re-begin. This should trigger error
9325     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9326     m_errorMonitor->VerifyFound();
9327
9328     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer ");
9329     VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
9330     // Reset attempt will trigger error due to incorrect CommandPool state
9331     vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags);
9332     m_errorMonitor->VerifyFound();
9333
9334     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from ");
9335     // Transition CB to RECORDED state
9336     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9337     // Now attempting to Begin will implicitly reset, which triggers error
9338     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9339     m_errorMonitor->VerifyFound();
9340 }
9341
9342 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
9343     // Attempt to Create Gfx Pipeline w/o a VS
9344     VkResult err;
9345
9346     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
9347
9348     ASSERT_NO_FATAL_FAILURE(InitState());
9349     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9350
9351     VkDescriptorPoolSize ds_type_count = {};
9352     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9353     ds_type_count.descriptorCount = 1;
9354
9355     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9356     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9357     ds_pool_ci.pNext = NULL;
9358     ds_pool_ci.maxSets = 1;
9359     ds_pool_ci.poolSizeCount = 1;
9360     ds_pool_ci.pPoolSizes = &ds_type_count;
9361
9362     VkDescriptorPool ds_pool;
9363     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9364     ASSERT_VK_SUCCESS(err);
9365
9366     VkDescriptorSetLayoutBinding dsl_binding = {};
9367     dsl_binding.binding = 0;
9368     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9369     dsl_binding.descriptorCount = 1;
9370     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9371     dsl_binding.pImmutableSamplers = NULL;
9372
9373     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9374     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9375     ds_layout_ci.pNext = NULL;
9376     ds_layout_ci.bindingCount = 1;
9377     ds_layout_ci.pBindings = &dsl_binding;
9378
9379     VkDescriptorSetLayout ds_layout;
9380     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9381     ASSERT_VK_SUCCESS(err);
9382
9383     VkDescriptorSet descriptorSet;
9384     VkDescriptorSetAllocateInfo alloc_info = {};
9385     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9386     alloc_info.descriptorSetCount = 1;
9387     alloc_info.descriptorPool = ds_pool;
9388     alloc_info.pSetLayouts = &ds_layout;
9389     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9390     ASSERT_VK_SUCCESS(err);
9391
9392     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9393     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9394     pipeline_layout_ci.setLayoutCount = 1;
9395     pipeline_layout_ci.pSetLayouts = &ds_layout;
9396
9397     VkPipelineLayout pipeline_layout;
9398     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9399     ASSERT_VK_SUCCESS(err);
9400
9401     VkViewport vp = {}; // Just need dummy vp to point to
9402     VkRect2D sc = {};   // dummy scissor to point to
9403
9404     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9405     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9406     vp_state_ci.scissorCount = 1;
9407     vp_state_ci.pScissors = &sc;
9408     vp_state_ci.viewportCount = 1;
9409     vp_state_ci.pViewports = &vp;
9410
9411     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9412     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9413     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9414     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9415     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9416     rs_state_ci.depthClampEnable = VK_FALSE;
9417     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9418     rs_state_ci.depthBiasEnable = VK_FALSE;
9419
9420     VkGraphicsPipelineCreateInfo gp_ci = {};
9421     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9422     gp_ci.pViewportState = &vp_state_ci;
9423     gp_ci.pRasterizationState = &rs_state_ci;
9424     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9425     gp_ci.layout = pipeline_layout;
9426     gp_ci.renderPass = renderPass();
9427
9428     VkPipelineCacheCreateInfo pc_ci = {};
9429     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9430     pc_ci.initialDataSize = 0;
9431     pc_ci.pInitialData = 0;
9432
9433     VkPipeline pipeline;
9434     VkPipelineCache pipelineCache;
9435
9436     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9437     ASSERT_VK_SUCCESS(err);
9438     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9439
9440     m_errorMonitor->VerifyFound();
9441
9442     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9443     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9444     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9445     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9446 }
9447 /*// TODO : This test should be good, but needs Tess support in compiler to run
9448 TEST_F(VkLayerTest, InvalidPatchControlPoints)
9449 {
9450     // Attempt to Create Gfx Pipeline w/o a VS
9451     VkResult        err;
9452
9453     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9454         "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
9455 primitive ");
9456
9457     ASSERT_NO_FATAL_FAILURE(InitState());
9458     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9459
9460     VkDescriptorPoolSize ds_type_count = {};
9461         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9462         ds_type_count.descriptorCount = 1;
9463
9464     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9465         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9466         ds_pool_ci.pNext = NULL;
9467         ds_pool_ci.poolSizeCount = 1;
9468         ds_pool_ci.pPoolSizes = &ds_type_count;
9469
9470     VkDescriptorPool ds_pool;
9471     err = vkCreateDescriptorPool(m_device->device(),
9472 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
9473     ASSERT_VK_SUCCESS(err);
9474
9475     VkDescriptorSetLayoutBinding dsl_binding = {};
9476         dsl_binding.binding = 0;
9477         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9478         dsl_binding.descriptorCount = 1;
9479         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9480         dsl_binding.pImmutableSamplers = NULL;
9481
9482     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9483         ds_layout_ci.sType =
9484 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9485         ds_layout_ci.pNext = NULL;
9486         ds_layout_ci.bindingCount = 1;
9487         ds_layout_ci.pBindings = &dsl_binding;
9488
9489     VkDescriptorSetLayout ds_layout;
9490     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
9491 &ds_layout);
9492     ASSERT_VK_SUCCESS(err);
9493
9494     VkDescriptorSet descriptorSet;
9495     err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
9496 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
9497     ASSERT_VK_SUCCESS(err);
9498
9499     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9500         pipeline_layout_ci.sType =
9501 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9502         pipeline_layout_ci.pNext = NULL;
9503         pipeline_layout_ci.setLayoutCount = 1;
9504         pipeline_layout_ci.pSetLayouts = &ds_layout;
9505
9506     VkPipelineLayout pipeline_layout;
9507     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
9508 &pipeline_layout);
9509     ASSERT_VK_SUCCESS(err);
9510
9511     VkPipelineShaderStageCreateInfo shaderStages[3];
9512     memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
9513
9514     VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
9515 this);
9516     // Just using VS txt for Tess shaders as we don't care about functionality
9517     VkShaderObj
9518 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9519 this);
9520     VkShaderObj
9521 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9522 this);
9523
9524     shaderStages[0].sType  =
9525 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9526     shaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
9527     shaderStages[0].shader = vs.handle();
9528     shaderStages[1].sType  =
9529 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9530     shaderStages[1].stage  = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
9531     shaderStages[1].shader = tc.handle();
9532     shaderStages[2].sType  =
9533 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9534     shaderStages[2].stage  = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
9535     shaderStages[2].shader = te.handle();
9536
9537     VkPipelineInputAssemblyStateCreateInfo iaCI = {};
9538         iaCI.sType =
9539 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9540         iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
9541
9542     VkPipelineTessellationStateCreateInfo tsCI = {};
9543         tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
9544         tsCI.patchControlPoints = 0; // This will cause an error
9545
9546     VkGraphicsPipelineCreateInfo gp_ci = {};
9547         gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9548         gp_ci.pNext = NULL;
9549         gp_ci.stageCount = 3;
9550         gp_ci.pStages = shaderStages;
9551         gp_ci.pVertexInputState = NULL;
9552         gp_ci.pInputAssemblyState = &iaCI;
9553         gp_ci.pTessellationState = &tsCI;
9554         gp_ci.pViewportState = NULL;
9555         gp_ci.pRasterizationState = NULL;
9556         gp_ci.pMultisampleState = NULL;
9557         gp_ci.pDepthStencilState = NULL;
9558         gp_ci.pColorBlendState = NULL;
9559         gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9560         gp_ci.layout = pipeline_layout;
9561         gp_ci.renderPass = renderPass();
9562
9563     VkPipelineCacheCreateInfo pc_ci = {};
9564         pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9565         pc_ci.pNext = NULL;
9566         pc_ci.initialSize = 0;
9567         pc_ci.initialData = 0;
9568         pc_ci.maxSize = 0;
9569
9570     VkPipeline pipeline;
9571     VkPipelineCache pipelineCache;
9572
9573     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
9574 &pipelineCache);
9575     ASSERT_VK_SUCCESS(err);
9576     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
9577 &gp_ci, NULL, &pipeline);
9578
9579     m_errorMonitor->VerifyFound();
9580
9581     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9582     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9583     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9584     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9585 }
9586 */
9587 // Set scissor and viewport counts to different numbers
9588 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) {
9589     VkResult err;
9590
9591     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9592                                          "Gfx Pipeline viewport count (1) must match scissor count (0).");
9593
9594     ASSERT_NO_FATAL_FAILURE(InitState());
9595     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9596
9597     VkDescriptorPoolSize ds_type_count = {};
9598     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9599     ds_type_count.descriptorCount = 1;
9600
9601     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9602     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9603     ds_pool_ci.maxSets = 1;
9604     ds_pool_ci.poolSizeCount = 1;
9605     ds_pool_ci.pPoolSizes = &ds_type_count;
9606
9607     VkDescriptorPool ds_pool;
9608     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9609     ASSERT_VK_SUCCESS(err);
9610
9611     VkDescriptorSetLayoutBinding dsl_binding = {};
9612     dsl_binding.binding = 0;
9613     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9614     dsl_binding.descriptorCount = 1;
9615     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9616
9617     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9618     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9619     ds_layout_ci.bindingCount = 1;
9620     ds_layout_ci.pBindings = &dsl_binding;
9621
9622     VkDescriptorSetLayout ds_layout;
9623     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9624     ASSERT_VK_SUCCESS(err);
9625
9626     VkDescriptorSet descriptorSet;
9627     VkDescriptorSetAllocateInfo alloc_info = {};
9628     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9629     alloc_info.descriptorSetCount = 1;
9630     alloc_info.descriptorPool = ds_pool;
9631     alloc_info.pSetLayouts = &ds_layout;
9632     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9633     ASSERT_VK_SUCCESS(err);
9634
9635     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9636     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9637     pipeline_layout_ci.setLayoutCount = 1;
9638     pipeline_layout_ci.pSetLayouts = &ds_layout;
9639
9640     VkPipelineLayout pipeline_layout;
9641     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9642     ASSERT_VK_SUCCESS(err);
9643
9644     VkViewport vp = {}; // Just need dummy vp to point to
9645
9646     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9647     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9648     vp_state_ci.scissorCount = 0;
9649     vp_state_ci.viewportCount = 1; // Count mismatch should cause error
9650     vp_state_ci.pViewports = &vp;
9651
9652     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9653     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9654     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9655     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9656     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9657     rs_state_ci.depthClampEnable = VK_FALSE;
9658     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9659     rs_state_ci.depthBiasEnable = VK_FALSE;
9660
9661     VkPipelineShaderStageCreateInfo shaderStages[2];
9662     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9663
9664     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9665     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9666     // but add it to be able to run on more devices
9667     shaderStages[0] = vs.GetStageCreateInfo();
9668     shaderStages[1] = fs.GetStageCreateInfo();
9669
9670     VkGraphicsPipelineCreateInfo gp_ci = {};
9671     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9672     gp_ci.stageCount = 2;
9673     gp_ci.pStages = shaderStages;
9674     gp_ci.pViewportState = &vp_state_ci;
9675     gp_ci.pRasterizationState = &rs_state_ci;
9676     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9677     gp_ci.layout = pipeline_layout;
9678     gp_ci.renderPass = renderPass();
9679
9680     VkPipelineCacheCreateInfo pc_ci = {};
9681     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9682
9683     VkPipeline pipeline;
9684     VkPipelineCache pipelineCache;
9685
9686     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9687     ASSERT_VK_SUCCESS(err);
9688     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9689
9690     m_errorMonitor->VerifyFound();
9691
9692     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9693     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9694     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9695     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9696 }
9697 // Don't set viewport state in PSO. This is an error b/c we always need this
9698 // state
9699 //  for the counts even if the data is going to be set dynamically.
9700 TEST_F(VkLayerTest, PSOViewportStateNotSet) {
9701     // Attempt to Create Gfx Pipeline w/o a VS
9702     VkResult err;
9703
9704     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if ");
9705
9706     ASSERT_NO_FATAL_FAILURE(InitState());
9707     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9708
9709     VkDescriptorPoolSize ds_type_count = {};
9710     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9711     ds_type_count.descriptorCount = 1;
9712
9713     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9714     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9715     ds_pool_ci.maxSets = 1;
9716     ds_pool_ci.poolSizeCount = 1;
9717     ds_pool_ci.pPoolSizes = &ds_type_count;
9718
9719     VkDescriptorPool ds_pool;
9720     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9721     ASSERT_VK_SUCCESS(err);
9722
9723     VkDescriptorSetLayoutBinding dsl_binding = {};
9724     dsl_binding.binding = 0;
9725     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9726     dsl_binding.descriptorCount = 1;
9727     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9728
9729     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9730     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9731     ds_layout_ci.bindingCount = 1;
9732     ds_layout_ci.pBindings = &dsl_binding;
9733
9734     VkDescriptorSetLayout ds_layout;
9735     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9736     ASSERT_VK_SUCCESS(err);
9737
9738     VkDescriptorSet descriptorSet;
9739     VkDescriptorSetAllocateInfo alloc_info = {};
9740     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9741     alloc_info.descriptorSetCount = 1;
9742     alloc_info.descriptorPool = ds_pool;
9743     alloc_info.pSetLayouts = &ds_layout;
9744     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9745     ASSERT_VK_SUCCESS(err);
9746
9747     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9748     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9749     pipeline_layout_ci.setLayoutCount = 1;
9750     pipeline_layout_ci.pSetLayouts = &ds_layout;
9751
9752     VkPipelineLayout pipeline_layout;
9753     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9754     ASSERT_VK_SUCCESS(err);
9755
9756     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9757     // Set scissor as dynamic to avoid second error
9758     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9759     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9760     dyn_state_ci.dynamicStateCount = 1;
9761     dyn_state_ci.pDynamicStates = &sc_state;
9762
9763     VkPipelineShaderStageCreateInfo shaderStages[2];
9764     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9765
9766     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9767     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9768     // but add it to be able to run on more devices
9769     shaderStages[0] = vs.GetStageCreateInfo();
9770     shaderStages[1] = fs.GetStageCreateInfo();
9771
9772     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9773     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9774     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9775     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9776     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9777     rs_state_ci.depthClampEnable = VK_FALSE;
9778     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9779     rs_state_ci.depthBiasEnable = VK_FALSE;
9780
9781     VkGraphicsPipelineCreateInfo gp_ci = {};
9782     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9783     gp_ci.stageCount = 2;
9784     gp_ci.pStages = shaderStages;
9785     gp_ci.pRasterizationState = &rs_state_ci;
9786     gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state
9787                                  // should cause validation error
9788     gp_ci.pDynamicState = &dyn_state_ci;
9789     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9790     gp_ci.layout = pipeline_layout;
9791     gp_ci.renderPass = renderPass();
9792
9793     VkPipelineCacheCreateInfo pc_ci = {};
9794     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9795
9796     VkPipeline pipeline;
9797     VkPipelineCache pipelineCache;
9798
9799     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9800     ASSERT_VK_SUCCESS(err);
9801     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9802
9803     m_errorMonitor->VerifyFound();
9804
9805     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9806     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9807     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9808     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9809 }
9810 // Create PSO w/o non-zero viewportCount but no viewport data
9811 // Then run second test where dynamic scissor count doesn't match PSO scissor
9812 // count
9813 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) {
9814     VkResult err;
9815
9816     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9817                                          "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
9818
9819     ASSERT_NO_FATAL_FAILURE(InitState());
9820
9821     if (!m_device->phy().features().multiViewport) {
9822         printf("Device does not support multiple viewports/scissors; skipped.\n");
9823         return;
9824     }
9825
9826     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9827
9828     VkDescriptorPoolSize ds_type_count = {};
9829     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9830     ds_type_count.descriptorCount = 1;
9831
9832     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9833     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9834     ds_pool_ci.maxSets = 1;
9835     ds_pool_ci.poolSizeCount = 1;
9836     ds_pool_ci.pPoolSizes = &ds_type_count;
9837
9838     VkDescriptorPool ds_pool;
9839     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9840     ASSERT_VK_SUCCESS(err);
9841
9842     VkDescriptorSetLayoutBinding dsl_binding = {};
9843     dsl_binding.binding = 0;
9844     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9845     dsl_binding.descriptorCount = 1;
9846     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9847
9848     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9849     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9850     ds_layout_ci.bindingCount = 1;
9851     ds_layout_ci.pBindings = &dsl_binding;
9852
9853     VkDescriptorSetLayout ds_layout;
9854     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9855     ASSERT_VK_SUCCESS(err);
9856
9857     VkDescriptorSet descriptorSet;
9858     VkDescriptorSetAllocateInfo alloc_info = {};
9859     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9860     alloc_info.descriptorSetCount = 1;
9861     alloc_info.descriptorPool = ds_pool;
9862     alloc_info.pSetLayouts = &ds_layout;
9863     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9864     ASSERT_VK_SUCCESS(err);
9865
9866     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9867     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9868     pipeline_layout_ci.setLayoutCount = 1;
9869     pipeline_layout_ci.pSetLayouts = &ds_layout;
9870
9871     VkPipelineLayout pipeline_layout;
9872     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9873     ASSERT_VK_SUCCESS(err);
9874
9875     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9876     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9877     vp_state_ci.viewportCount = 1;
9878     vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error
9879     vp_state_ci.scissorCount = 1;
9880     vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error
9881
9882     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9883     // Set scissor as dynamic to avoid that error
9884     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9885     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9886     dyn_state_ci.dynamicStateCount = 1;
9887     dyn_state_ci.pDynamicStates = &sc_state;
9888
9889     VkPipelineShaderStageCreateInfo shaderStages[2];
9890     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9891
9892     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9893     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9894     // but add it to be able to run on more devices
9895     shaderStages[0] = vs.GetStageCreateInfo();
9896     shaderStages[1] = fs.GetStageCreateInfo();
9897
9898     VkPipelineVertexInputStateCreateInfo vi_ci = {};
9899     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
9900     vi_ci.pNext = nullptr;
9901     vi_ci.vertexBindingDescriptionCount = 0;
9902     vi_ci.pVertexBindingDescriptions = nullptr;
9903     vi_ci.vertexAttributeDescriptionCount = 0;
9904     vi_ci.pVertexAttributeDescriptions = nullptr;
9905
9906     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
9907     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9908     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9909
9910     VkPipelineRasterizationStateCreateInfo rs_ci = {};
9911     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9912     rs_ci.pNext = nullptr;
9913
9914     VkPipelineColorBlendAttachmentState att = {};
9915     att.blendEnable = VK_FALSE;
9916     att.colorWriteMask = 0xf;
9917
9918     VkPipelineColorBlendStateCreateInfo cb_ci = {};
9919     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
9920     cb_ci.pNext = nullptr;
9921     cb_ci.attachmentCount = 1;
9922     cb_ci.pAttachments = &att;
9923
9924     VkGraphicsPipelineCreateInfo gp_ci = {};
9925     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9926     gp_ci.stageCount = 2;
9927     gp_ci.pStages = shaderStages;
9928     gp_ci.pVertexInputState = &vi_ci;
9929     gp_ci.pInputAssemblyState = &ia_ci;
9930     gp_ci.pViewportState = &vp_state_ci;
9931     gp_ci.pRasterizationState = &rs_ci;
9932     gp_ci.pColorBlendState = &cb_ci;
9933     gp_ci.pDynamicState = &dyn_state_ci;
9934     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9935     gp_ci.layout = pipeline_layout;
9936     gp_ci.renderPass = renderPass();
9937
9938     VkPipelineCacheCreateInfo pc_ci = {};
9939     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9940
9941     VkPipeline pipeline;
9942     VkPipelineCache pipelineCache;
9943
9944     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9945     ASSERT_VK_SUCCESS(err);
9946     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9947
9948     m_errorMonitor->VerifyFound();
9949
9950     // Now hit second fail case where we set scissor w/ different count than PSO
9951     // First need to successfully create the PSO from above by setting
9952     // pViewports
9953     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
9954
9955     VkViewport vp = {}; // Just need dummy vp to point to
9956     vp_state_ci.pViewports = &vp;
9957     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9958     ASSERT_VK_SUCCESS(err);
9959     BeginCommandBuffer();
9960     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
9961     VkRect2D scissors[1] = {}; // don't care about data
9962     // Count of 2 doesn't match PSO count of 1
9963     vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
9964     Draw(1, 0, 0, 0);
9965
9966     m_errorMonitor->VerifyFound();
9967
9968     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9969     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9970     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9971     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9972     vkDestroyPipeline(m_device->device(), pipeline, NULL);
9973 }
9974 // Create PSO w/o non-zero scissorCount but no scissor data
9975 // Then run second test where dynamic viewportCount doesn't match PSO
9976 // viewportCount
9977 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) {
9978     VkResult err;
9979
9980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
9981
9982     ASSERT_NO_FATAL_FAILURE(InitState());
9983
9984     if (!m_device->phy().features().multiViewport) {
9985         printf("Device does not support multiple viewports/scissors; skipped.\n");
9986         return;
9987     }
9988
9989     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9990
9991     VkDescriptorPoolSize ds_type_count = {};
9992     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9993     ds_type_count.descriptorCount = 1;
9994
9995     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9996     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9997     ds_pool_ci.maxSets = 1;
9998     ds_pool_ci.poolSizeCount = 1;
9999     ds_pool_ci.pPoolSizes = &ds_type_count;
10000
10001     VkDescriptorPool ds_pool;
10002     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10003     ASSERT_VK_SUCCESS(err);
10004
10005     VkDescriptorSetLayoutBinding dsl_binding = {};
10006     dsl_binding.binding = 0;
10007     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10008     dsl_binding.descriptorCount = 1;
10009     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10010
10011     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10012     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10013     ds_layout_ci.bindingCount = 1;
10014     ds_layout_ci.pBindings = &dsl_binding;
10015
10016     VkDescriptorSetLayout ds_layout;
10017     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10018     ASSERT_VK_SUCCESS(err);
10019
10020     VkDescriptorSet descriptorSet;
10021     VkDescriptorSetAllocateInfo alloc_info = {};
10022     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10023     alloc_info.descriptorSetCount = 1;
10024     alloc_info.descriptorPool = ds_pool;
10025     alloc_info.pSetLayouts = &ds_layout;
10026     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10027     ASSERT_VK_SUCCESS(err);
10028
10029     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10030     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10031     pipeline_layout_ci.setLayoutCount = 1;
10032     pipeline_layout_ci.pSetLayouts = &ds_layout;
10033
10034     VkPipelineLayout pipeline_layout;
10035     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10036     ASSERT_VK_SUCCESS(err);
10037
10038     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10039     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10040     vp_state_ci.scissorCount = 1;
10041     vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error
10042     vp_state_ci.viewportCount = 1;
10043     vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error
10044
10045     VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT;
10046     // Set scissor as dynamic to avoid that error
10047     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10048     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10049     dyn_state_ci.dynamicStateCount = 1;
10050     dyn_state_ci.pDynamicStates = &vp_state;
10051
10052     VkPipelineShaderStageCreateInfo shaderStages[2];
10053     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10054
10055     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10056     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
10057     // but add it to be able to run on more devices
10058     shaderStages[0] = vs.GetStageCreateInfo();
10059     shaderStages[1] = fs.GetStageCreateInfo();
10060
10061     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10062     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10063     vi_ci.pNext = nullptr;
10064     vi_ci.vertexBindingDescriptionCount = 0;
10065     vi_ci.pVertexBindingDescriptions = nullptr;
10066     vi_ci.vertexAttributeDescriptionCount = 0;
10067     vi_ci.pVertexAttributeDescriptions = nullptr;
10068
10069     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10070     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10071     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10072
10073     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10074     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10075     rs_ci.pNext = nullptr;
10076
10077     VkPipelineColorBlendAttachmentState att = {};
10078     att.blendEnable = VK_FALSE;
10079     att.colorWriteMask = 0xf;
10080
10081     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10082     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10083     cb_ci.pNext = nullptr;
10084     cb_ci.attachmentCount = 1;
10085     cb_ci.pAttachments = &att;
10086
10087     VkGraphicsPipelineCreateInfo gp_ci = {};
10088     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10089     gp_ci.stageCount = 2;
10090     gp_ci.pStages = shaderStages;
10091     gp_ci.pVertexInputState = &vi_ci;
10092     gp_ci.pInputAssemblyState = &ia_ci;
10093     gp_ci.pViewportState = &vp_state_ci;
10094     gp_ci.pRasterizationState = &rs_ci;
10095     gp_ci.pColorBlendState = &cb_ci;
10096     gp_ci.pDynamicState = &dyn_state_ci;
10097     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10098     gp_ci.layout = pipeline_layout;
10099     gp_ci.renderPass = renderPass();
10100
10101     VkPipelineCacheCreateInfo pc_ci = {};
10102     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10103
10104     VkPipeline pipeline;
10105     VkPipelineCache pipelineCache;
10106
10107     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10108     ASSERT_VK_SUCCESS(err);
10109     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10110
10111     m_errorMonitor->VerifyFound();
10112
10113     // Now hit second fail case where we set scissor w/ different count than PSO
10114     // First need to successfully create the PSO from above by setting
10115     // pViewports
10116     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
10117
10118     VkRect2D sc = {}; // Just need dummy vp to point to
10119     vp_state_ci.pScissors = &sc;
10120     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10121     ASSERT_VK_SUCCESS(err);
10122     BeginCommandBuffer();
10123     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10124     VkViewport viewports[1] = {}; // don't care about data
10125     // Count of 2 doesn't match PSO count of 1
10126     vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
10127     Draw(1, 0, 0, 0);
10128
10129     m_errorMonitor->VerifyFound();
10130
10131     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10132     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10133     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10134     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10135     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10136 }
10137
10138 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
10139     VkResult err;
10140
10141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10142
10143     ASSERT_NO_FATAL_FAILURE(InitState());
10144     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10145
10146     VkDescriptorPoolSize ds_type_count = {};
10147     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10148     ds_type_count.descriptorCount = 1;
10149
10150     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10151     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10152     ds_pool_ci.maxSets = 1;
10153     ds_pool_ci.poolSizeCount = 1;
10154     ds_pool_ci.pPoolSizes = &ds_type_count;
10155
10156     VkDescriptorPool ds_pool;
10157     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10158     ASSERT_VK_SUCCESS(err);
10159
10160     VkDescriptorSetLayoutBinding dsl_binding = {};
10161     dsl_binding.binding = 0;
10162     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10163     dsl_binding.descriptorCount = 1;
10164     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10165
10166     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10167     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10168     ds_layout_ci.bindingCount = 1;
10169     ds_layout_ci.pBindings = &dsl_binding;
10170
10171     VkDescriptorSetLayout ds_layout;
10172     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10173     ASSERT_VK_SUCCESS(err);
10174
10175     VkDescriptorSet descriptorSet;
10176     VkDescriptorSetAllocateInfo alloc_info = {};
10177     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10178     alloc_info.descriptorSetCount = 1;
10179     alloc_info.descriptorPool = ds_pool;
10180     alloc_info.pSetLayouts = &ds_layout;
10181     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10182     ASSERT_VK_SUCCESS(err);
10183
10184     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10185     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10186     pipeline_layout_ci.setLayoutCount = 1;
10187     pipeline_layout_ci.pSetLayouts = &ds_layout;
10188
10189     VkPipelineLayout pipeline_layout;
10190     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10191     ASSERT_VK_SUCCESS(err);
10192
10193     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10194     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10195     vp_state_ci.scissorCount = 1;
10196     vp_state_ci.pScissors = NULL;
10197     vp_state_ci.viewportCount = 1;
10198     vp_state_ci.pViewports = NULL;
10199
10200     VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
10201     // Set scissor as dynamic to avoid that error
10202     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10203     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10204     dyn_state_ci.dynamicStateCount = 2;
10205     dyn_state_ci.pDynamicStates = dynamic_states;
10206
10207     VkPipelineShaderStageCreateInfo shaderStages[2];
10208     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10209
10210     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10211     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
10212                    this); // TODO - We shouldn't need a fragment shader
10213                           // but add it to be able to run on more devices
10214     shaderStages[0] = vs.GetStageCreateInfo();
10215     shaderStages[1] = fs.GetStageCreateInfo();
10216
10217     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10218     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10219     vi_ci.pNext = nullptr;
10220     vi_ci.vertexBindingDescriptionCount = 0;
10221     vi_ci.pVertexBindingDescriptions = nullptr;
10222     vi_ci.vertexAttributeDescriptionCount = 0;
10223     vi_ci.pVertexAttributeDescriptions = nullptr;
10224
10225     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10226     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10227     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10228
10229     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10230     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10231     rs_ci.pNext = nullptr;
10232
10233     // Check too low (line width of -1.0f).
10234     rs_ci.lineWidth = -1.0f;
10235
10236     VkPipelineColorBlendAttachmentState att = {};
10237     att.blendEnable = VK_FALSE;
10238     att.colorWriteMask = 0xf;
10239
10240     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10241     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10242     cb_ci.pNext = nullptr;
10243     cb_ci.attachmentCount = 1;
10244     cb_ci.pAttachments = &att;
10245
10246     VkGraphicsPipelineCreateInfo gp_ci = {};
10247     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10248     gp_ci.stageCount = 2;
10249     gp_ci.pStages = shaderStages;
10250     gp_ci.pVertexInputState = &vi_ci;
10251     gp_ci.pInputAssemblyState = &ia_ci;
10252     gp_ci.pViewportState = &vp_state_ci;
10253     gp_ci.pRasterizationState = &rs_ci;
10254     gp_ci.pColorBlendState = &cb_ci;
10255     gp_ci.pDynamicState = &dyn_state_ci;
10256     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10257     gp_ci.layout = pipeline_layout;
10258     gp_ci.renderPass = renderPass();
10259
10260     VkPipelineCacheCreateInfo pc_ci = {};
10261     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10262
10263     VkPipeline pipeline;
10264     VkPipelineCache pipelineCache;
10265
10266     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10267     ASSERT_VK_SUCCESS(err);
10268     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10269
10270     m_errorMonitor->VerifyFound();
10271     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10272
10273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10274
10275     // Check too high (line width of 65536.0f).
10276     rs_ci.lineWidth = 65536.0f;
10277
10278     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10279     ASSERT_VK_SUCCESS(err);
10280     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10281
10282     m_errorMonitor->VerifyFound();
10283     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10284
10285     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10286
10287     dyn_state_ci.dynamicStateCount = 3;
10288
10289     rs_ci.lineWidth = 1.0f;
10290
10291     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10292     ASSERT_VK_SUCCESS(err);
10293     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10294     BeginCommandBuffer();
10295     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10296
10297     // Check too low with dynamic setting.
10298     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f);
10299     m_errorMonitor->VerifyFound();
10300
10301     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10302
10303     // Check too high with dynamic setting.
10304     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f);
10305     m_errorMonitor->VerifyFound();
10306     EndCommandBuffer();
10307
10308     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10309     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10310     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10311     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10312     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10313 }
10314
10315 TEST_F(VkLayerTest, NullRenderPass) {
10316     // Bind a NULL RenderPass
10317     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10318                                          "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
10319
10320     ASSERT_NO_FATAL_FAILURE(InitState());
10321     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10322
10323     BeginCommandBuffer();
10324     // Don't care about RenderPass handle b/c error should be flagged before
10325     // that
10326     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
10327
10328     m_errorMonitor->VerifyFound();
10329 }
10330
10331 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
10332     // Bind a BeginRenderPass within an active RenderPass
10333     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10334                                          "It is invalid to issue this call inside an active render pass");
10335
10336     ASSERT_NO_FATAL_FAILURE(InitState());
10337     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10338
10339     BeginCommandBuffer();
10340     // Just create a dummy Renderpass that's non-NULL so we can get to the
10341     // proper error
10342     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10343
10344     m_errorMonitor->VerifyFound();
10345 }
10346
10347 TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
10348     m_errorMonitor->ExpectSuccess();
10349
10350     ASSERT_NO_FATAL_FAILURE(InitState());
10351     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10352
10353     BeginCommandBuffer();                                   // framework implicitly begins the renderpass.
10354     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
10355
10356     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
10357     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10358     m_errorMonitor->VerifyNotFound();
10359     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10360     m_errorMonitor->VerifyNotFound();
10361     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10362     m_errorMonitor->VerifyNotFound();
10363
10364     m_commandBuffer->EndCommandBuffer();
10365     m_errorMonitor->VerifyNotFound();
10366 }
10367
10368 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
10369     TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
10370                      "the number of renderPass attachments that use loadOp"
10371                      "VK_ATTACHMENT_LOAD_OP_CLEAR.");
10372
10373     ASSERT_NO_FATAL_FAILURE(InitState());
10374     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10375
10376     // Create a renderPass with a single attachment that uses loadOp CLEAR
10377     VkAttachmentReference attach = {};
10378     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
10379     VkSubpassDescription subpass = {};
10380     subpass.inputAttachmentCount = 1;
10381     subpass.pInputAttachments = &attach;
10382     VkRenderPassCreateInfo rpci = {};
10383     rpci.subpassCount = 1;
10384     rpci.pSubpasses = &subpass;
10385     rpci.attachmentCount = 1;
10386     VkAttachmentDescription attach_desc = {};
10387     attach_desc.format = VK_FORMAT_UNDEFINED;
10388     // Set loadOp to CLEAR
10389     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10390     rpci.pAttachments = &attach_desc;
10391     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10392     VkRenderPass rp;
10393     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
10394
10395     VkCommandBufferInheritanceInfo hinfo = {};
10396     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10397     hinfo.renderPass = VK_NULL_HANDLE;
10398     hinfo.subpass = 0;
10399     hinfo.framebuffer = VK_NULL_HANDLE;
10400     hinfo.occlusionQueryEnable = VK_FALSE;
10401     hinfo.queryFlags = 0;
10402     hinfo.pipelineStatistics = 0;
10403     VkCommandBufferBeginInfo info = {};
10404     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
10405     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10406     info.pInheritanceInfo = &hinfo;
10407
10408     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
10409     VkRenderPassBeginInfo rp_begin = {};
10410     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
10411     rp_begin.pNext = NULL;
10412     rp_begin.renderPass = renderPass();
10413     rp_begin.framebuffer = framebuffer();
10414     rp_begin.clearValueCount = 0; // Should be 1
10415
10416     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but "
10417                                                                         "there must be at least 1 entries in "
10418                                                                         "pClearValues array to account for ");
10419
10420     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
10421
10422     m_errorMonitor->VerifyFound();
10423
10424     vkDestroyRenderPass(m_device->device(), rp, NULL);
10425 }
10426
10427 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
10428
10429     TEST_DESCRIPTION("End a command buffer with an active render pass");
10430
10431     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10432                                          "It is invalid to issue this call inside an active render pass");
10433
10434     ASSERT_NO_FATAL_FAILURE(InitState());
10435     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10436
10437     // The framework's BeginCommandBuffer calls CreateRenderPass
10438     BeginCommandBuffer();
10439
10440     // Call directly into vkEndCommandBuffer instead of the
10441     // the framework's EndCommandBuffer, which inserts a
10442     // vkEndRenderPass
10443     vkEndCommandBuffer(m_commandBuffer->GetBufferHandle());
10444
10445     m_errorMonitor->VerifyFound();
10446
10447     // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
10448     // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
10449 }
10450
10451 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
10452     // Call CmdFillBuffer within an active renderpass
10453     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10454                                          "It is invalid to issue this call inside an active render pass");
10455
10456     ASSERT_NO_FATAL_FAILURE(InitState());
10457     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10458
10459     // Renderpass is started here
10460     BeginCommandBuffer();
10461
10462     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10463     vk_testing::Buffer dstBuffer;
10464     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10465
10466     m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
10467
10468     m_errorMonitor->VerifyFound();
10469 }
10470
10471 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
10472     // Call CmdUpdateBuffer within an active renderpass
10473     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10474                                          "It is invalid to issue this call inside an active render pass");
10475
10476     ASSERT_NO_FATAL_FAILURE(InitState());
10477     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10478
10479     // Renderpass is started here
10480     BeginCommandBuffer();
10481
10482     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10483     vk_testing::Buffer dstBuffer;
10484     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10485
10486     VkDeviceSize dstOffset = 0;
10487     VkDeviceSize dataSize = 1024;
10488     const void *pData = NULL;
10489
10490     vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData);
10491
10492     m_errorMonitor->VerifyFound();
10493 }
10494
10495 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
10496     // Call CmdClearColorImage within an active RenderPass
10497     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10498                                          "It is invalid to issue this call inside an active render pass");
10499
10500     ASSERT_NO_FATAL_FAILURE(InitState());
10501     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10502
10503     // Renderpass is started here
10504     BeginCommandBuffer();
10505
10506     VkClearColorValue clear_color;
10507     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
10508     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10509     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10510     const int32_t tex_width = 32;
10511     const int32_t tex_height = 32;
10512     VkImageCreateInfo image_create_info = {};
10513     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10514     image_create_info.pNext = NULL;
10515     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10516     image_create_info.format = tex_format;
10517     image_create_info.extent.width = tex_width;
10518     image_create_info.extent.height = tex_height;
10519     image_create_info.extent.depth = 1;
10520     image_create_info.mipLevels = 1;
10521     image_create_info.arrayLayers = 1;
10522     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10523     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
10524     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10525
10526     vk_testing::Image dstImage;
10527     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10528
10529     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
10530
10531     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
10532
10533     m_errorMonitor->VerifyFound();
10534 }
10535
10536 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) {
10537     // Call CmdClearDepthStencilImage within an active RenderPass
10538     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10539                                          "It is invalid to issue this call inside an active render pass");
10540
10541     ASSERT_NO_FATAL_FAILURE(InitState());
10542     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10543
10544     // Renderpass is started here
10545     BeginCommandBuffer();
10546
10547     VkClearDepthStencilValue clear_value = {0};
10548     VkMemoryPropertyFlags reqs = 0;
10549     VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
10550     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10551     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
10552     image_create_info.extent.width = 64;
10553     image_create_info.extent.height = 64;
10554     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10555     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
10556
10557     vk_testing::Image dstImage;
10558     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10559
10560     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
10561
10562     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(),
10563                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range);
10564
10565     m_errorMonitor->VerifyFound();
10566 }
10567
10568 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
10569     // Call CmdClearAttachmentss outside of an active RenderPass
10570     VkResult err;
10571
10572     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call "
10573                                                                         "must be issued inside an active "
10574                                                                         "render pass");
10575
10576     ASSERT_NO_FATAL_FAILURE(InitState());
10577     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10578
10579     // Start no RenderPass
10580     err = m_commandBuffer->BeginCommandBuffer();
10581     ASSERT_VK_SUCCESS(err);
10582
10583     VkClearAttachment color_attachment;
10584     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10585     color_attachment.clearValue.color.float32[0] = 0;
10586     color_attachment.clearValue.color.float32[1] = 0;
10587     color_attachment.clearValue.color.float32[2] = 0;
10588     color_attachment.clearValue.color.float32[3] = 0;
10589     color_attachment.colorAttachment = 0;
10590     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
10591     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
10592
10593     m_errorMonitor->VerifyFound();
10594 }
10595
10596 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
10597     TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is "
10598                      "called too many times in a renderpass instance");
10599
10600     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance "
10601                                                                         "beyond final subpass");
10602
10603     ASSERT_NO_FATAL_FAILURE(InitState());
10604     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10605
10606     BeginCommandBuffer();
10607
10608     // error here.
10609     vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE);
10610     m_errorMonitor->VerifyFound();
10611
10612     EndCommandBuffer();
10613 }
10614
10615 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
10616     TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is "
10617                      "called before the final subpass has been reached");
10618
10619     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching "
10620                                                                         "final subpass");
10621
10622     ASSERT_NO_FATAL_FAILURE(InitState());
10623     VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
10624                                   {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
10625
10626     VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
10627
10628     VkRenderPass rp;
10629     VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
10630     ASSERT_VK_SUCCESS(err);
10631
10632     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
10633
10634     VkFramebuffer fb;
10635     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
10636     ASSERT_VK_SUCCESS(err);
10637
10638     m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin
10639
10640     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
10641
10642     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
10643
10644     // Error here.
10645     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10646     m_errorMonitor->VerifyFound();
10647
10648     // Clean up.
10649     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
10650     vkDestroyRenderPass(m_device->device(), rp, nullptr);
10651 }
10652
10653 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
10654     // Try to add a buffer memory barrier with no buffer.
10655     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10656                                          "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
10657
10658     ASSERT_NO_FATAL_FAILURE(InitState());
10659     BeginCommandBuffer();
10660
10661     VkBufferMemoryBarrier buf_barrier = {};
10662     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10663     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10664     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10665     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10666     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10667     buf_barrier.buffer = VK_NULL_HANDLE;
10668     buf_barrier.offset = 0;
10669     buf_barrier.size = VK_WHOLE_SIZE;
10670     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10671                          nullptr, 1, &buf_barrier, 0, nullptr);
10672
10673     m_errorMonitor->VerifyFound();
10674 }
10675
10676 TEST_F(VkLayerTest, InvalidBarriers) {
10677     TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
10678
10679     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass");
10680
10681     ASSERT_NO_FATAL_FAILURE(InitState());
10682     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10683
10684     VkMemoryBarrier mem_barrier = {};
10685     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
10686     mem_barrier.pNext = NULL;
10687     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10688     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10689     BeginCommandBuffer();
10690     // BeginCommandBuffer() starts a render pass
10691     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
10692                          &mem_barrier, 0, nullptr, 0, nullptr);
10693     m_errorMonitor->VerifyFound();
10694
10695     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
10696     VkImageObj image(m_device);
10697     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10698     ASSERT_TRUE(image.initialized());
10699     VkImageMemoryBarrier img_barrier = {};
10700     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10701     img_barrier.pNext = NULL;
10702     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10703     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10704     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10705     // New layout can't be UNDEFINED
10706     img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10707     img_barrier.image = image.handle();
10708     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10709     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10710     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10711     img_barrier.subresourceRange.baseArrayLayer = 0;
10712     img_barrier.subresourceRange.baseMipLevel = 0;
10713     img_barrier.subresourceRange.layerCount = 1;
10714     img_barrier.subresourceRange.levelCount = 1;
10715     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10716                          nullptr, 0, nullptr, 1, &img_barrier);
10717     m_errorMonitor->VerifyFound();
10718     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10719
10720     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the "
10721                                                                         "baseArrayLayer");
10722     // baseArrayLayer + layerCount must be <= image's arrayLayers
10723     img_barrier.subresourceRange.baseArrayLayer = 1;
10724     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10725                          nullptr, 0, nullptr, 1, &img_barrier);
10726     m_errorMonitor->VerifyFound();
10727     img_barrier.subresourceRange.baseArrayLayer = 0;
10728
10729     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel");
10730     // baseMipLevel + levelCount must be <= image's mipLevels
10731     img_barrier.subresourceRange.baseMipLevel = 1;
10732     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10733                          nullptr, 0, nullptr, 1, &img_barrier);
10734     m_errorMonitor->VerifyFound();
10735     img_barrier.subresourceRange.baseMipLevel = 0;
10736
10737     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
10738     vk_testing::Buffer buffer;
10739     buffer.init(*m_device, 256);
10740     VkBufferMemoryBarrier buf_barrier = {};
10741     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10742     buf_barrier.pNext = NULL;
10743     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10744     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10745     buf_barrier.buffer = buffer.handle();
10746     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10747     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10748     buf_barrier.offset = 0;
10749     buf_barrier.size = VK_WHOLE_SIZE;
10750     // Can't send buffer barrier during a render pass
10751     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10752                          nullptr, 1, &buf_barrier, 0, nullptr);
10753     m_errorMonitor->VerifyFound();
10754     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10755
10756     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
10757     buf_barrier.offset = 257;
10758     // Offset greater than total size
10759     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10760                          nullptr, 1, &buf_barrier, 0, nullptr);
10761     m_errorMonitor->VerifyFound();
10762     buf_barrier.offset = 0;
10763
10764     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
10765     buf_barrier.size = 257;
10766     // Size greater than total size
10767     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10768                          nullptr, 1, &buf_barrier, 0, nullptr);
10769     m_errorMonitor->VerifyFound();
10770
10771     // Now exercise barrier aspect bit errors, first DS
10772     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must "
10773                                                                         "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
10774                                                                         "VK_IMAGE_ASPECT_STENCIL_BIT set.");
10775     VkDepthStencilObj ds_image(m_device);
10776     ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
10777     ASSERT_TRUE(ds_image.initialized());
10778     img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10779     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10780     img_barrier.image = ds_image.handle();
10781     // Use of COLOR aspect on DS image is error
10782     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10783     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10784                          nullptr, 0, nullptr, 1, &img_barrier);
10785     m_errorMonitor->VerifyFound();
10786     // Now test depth-only
10787     VkFormatProperties format_props;
10788
10789     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
10790     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10791         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must "
10792                                                                             "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
10793         VkDepthStencilObj d_image(m_device);
10794         d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
10795         ASSERT_TRUE(d_image.initialized());
10796         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10797         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10798         img_barrier.image = d_image.handle();
10799         // Use of COLOR aspect on depth image is error
10800         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10801         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10802                              0, nullptr, 0, nullptr, 1, &img_barrier);
10803         m_errorMonitor->VerifyFound();
10804     }
10805     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
10806     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10807         // Now test stencil-only
10808         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must "
10809                                                                             "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
10810         VkDepthStencilObj s_image(m_device);
10811         s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
10812         ASSERT_TRUE(s_image.initialized());
10813         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10814         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10815         img_barrier.image = s_image.handle();
10816         // Use of COLOR aspect on depth image is error
10817         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10818         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10819                              0, nullptr, 0, nullptr, 1, &img_barrier);
10820         m_errorMonitor->VerifyFound();
10821     }
10822     // Finally test color
10823     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
10824                                                                         "have VK_IMAGE_ASPECT_COLOR_BIT set.");
10825     VkImageObj c_image(m_device);
10826     c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10827     ASSERT_TRUE(c_image.initialized());
10828     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10829     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10830     img_barrier.image = c_image.handle();
10831     // Set aspect to depth (non-color)
10832     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
10833     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10834                          nullptr, 0, nullptr, 1, &img_barrier);
10835     m_errorMonitor->VerifyFound();
10836 }
10837
10838 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
10839     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
10840
10841     m_errorMonitor->SetDesiredFailureMsg(
10842         VK_DEBUG_REPORT_WARNING_BIT_EXT,
10843         "must have required access bit");
10844     ASSERT_NO_FATAL_FAILURE(InitState());
10845     VkImageObj image(m_device);
10846     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10847     ASSERT_TRUE(image.initialized());
10848
10849     VkImageMemoryBarrier barrier = {};
10850     VkImageSubresourceRange range;
10851     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10852     barrier.srcAccessMask = 0;
10853     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
10854     barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
10855     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10856     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10857     barrier.image = image.handle();
10858     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10859     range.baseMipLevel = 0;
10860     range.levelCount = 1;
10861     range.baseArrayLayer = 0;
10862     range.layerCount = 1;
10863     barrier.subresourceRange = range;
10864     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
10865     cmdbuf.BeginCommandBuffer();
10866     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10867                            &barrier);
10868     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10869     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10870     barrier.srcAccessMask = 0;
10871     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
10872     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10873                            &barrier);
10874
10875     m_errorMonitor->VerifyFound();
10876 }
10877
10878 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
10879     // Bind a BeginRenderPass within an active RenderPass
10880     VkResult err;
10881
10882     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
10883
10884     ASSERT_NO_FATAL_FAILURE(InitState());
10885     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10886     uint32_t qfi = 0;
10887     VkBufferCreateInfo buffCI = {};
10888     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10889     buffCI.size = 1024;
10890     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10891     buffCI.queueFamilyIndexCount = 1;
10892     buffCI.pQueueFamilyIndices = &qfi;
10893
10894     VkBuffer ib;
10895     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10896     ASSERT_VK_SUCCESS(err);
10897
10898     BeginCommandBuffer();
10899     ASSERT_VK_SUCCESS(err);
10900     // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
10901     // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10902     // Should error before calling to driver so don't care about actual data
10903     vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16);
10904
10905     m_errorMonitor->VerifyFound();
10906
10907     vkDestroyBuffer(m_device->device(), ib, NULL);
10908 }
10909
10910 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
10911     // Create an out-of-range queueFamilyIndex
10912     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10913                                          "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one "
10914                                          "of the indices specified when the device was created, via the "
10915                                          "VkDeviceQueueCreateInfo structure.");
10916
10917     ASSERT_NO_FATAL_FAILURE(InitState());
10918     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10919     VkBufferCreateInfo buffCI = {};
10920     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10921     buffCI.size = 1024;
10922     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10923     buffCI.queueFamilyIndexCount = 1;
10924     // Introduce failure by specifying invalid queue_family_index
10925     uint32_t qfi = 777;
10926     buffCI.pQueueFamilyIndices = &qfi;
10927     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
10928
10929     VkBuffer ib;
10930     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10931
10932     m_errorMonitor->VerifyFound();
10933     vkDestroyBuffer(m_device->device(), ib, NULL);
10934 }
10935
10936 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
10937     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
10938                      " (should only be secondary)");
10939
10940     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
10941
10942     ASSERT_NO_FATAL_FAILURE(InitState());
10943     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10944
10945     BeginCommandBuffer();
10946
10947     VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
10948     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
10949
10950     m_errorMonitor->VerifyFound();
10951 }
10952
10953 TEST_F(VkLayerTest, DSUsageBitsErrors) {
10954     TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
10955                      "that do not have correct usage bits sets.");
10956     VkResult err;
10957
10958     ASSERT_NO_FATAL_FAILURE(InitState());
10959     VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10960     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10961         ds_type_count[i].type = VkDescriptorType(i);
10962         ds_type_count[i].descriptorCount = 1;
10963     }
10964     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10965     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10966     ds_pool_ci.pNext = NULL;
10967     ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10968     ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10969     ds_pool_ci.pPoolSizes = ds_type_count;
10970
10971     VkDescriptorPool ds_pool;
10972     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10973     ASSERT_VK_SUCCESS(err);
10974
10975     // Create 10 layouts where each has a single descriptor of different type
10976     VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10977     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10978         dsl_binding[i].binding = 0;
10979         dsl_binding[i].descriptorType = VkDescriptorType(i);
10980         dsl_binding[i].descriptorCount = 1;
10981         dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
10982         dsl_binding[i].pImmutableSamplers = NULL;
10983     }
10984
10985     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10986     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10987     ds_layout_ci.pNext = NULL;
10988     ds_layout_ci.bindingCount = 1;
10989     VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
10990     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10991         ds_layout_ci.pBindings = dsl_binding + i;
10992         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i);
10993         ASSERT_VK_SUCCESS(err);
10994     }
10995     VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10996     VkDescriptorSetAllocateInfo alloc_info = {};
10997     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10998     alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10999     alloc_info.descriptorPool = ds_pool;
11000     alloc_info.pSetLayouts = ds_layouts;
11001     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
11002     ASSERT_VK_SUCCESS(err);
11003
11004     // Create a buffer & bufferView to be used for invalid updates
11005     VkBufferCreateInfo buff_ci = {};
11006     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11007     // This usage is not valid for any descriptor type
11008     buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
11009     buff_ci.size = 256;
11010     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11011     VkBuffer buffer;
11012     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11013     ASSERT_VK_SUCCESS(err);
11014
11015     VkBufferViewCreateInfo buff_view_ci = {};
11016     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11017     buff_view_ci.buffer = buffer;
11018     buff_view_ci.format = VK_FORMAT_R8_UNORM;
11019     buff_view_ci.range = VK_WHOLE_SIZE;
11020     VkBufferView buff_view;
11021     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11022     ASSERT_VK_SUCCESS(err);
11023
11024     // Create an image to be used for invalid updates
11025     VkImageCreateInfo image_ci = {};
11026     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11027     image_ci.imageType = VK_IMAGE_TYPE_2D;
11028     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11029     image_ci.extent.width = 64;
11030     image_ci.extent.height = 64;
11031     image_ci.extent.depth = 1;
11032     image_ci.mipLevels = 1;
11033     image_ci.arrayLayers = 1;
11034     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11035     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11036     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11037     // This usage is not valid for any descriptor type
11038     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11039     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11040     VkImage image;
11041     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11042     ASSERT_VK_SUCCESS(err);
11043     // Bind memory to image
11044     VkMemoryRequirements mem_reqs;
11045     VkDeviceMemory image_mem;
11046     bool pass;
11047     VkMemoryAllocateInfo mem_alloc = {};
11048     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11049     mem_alloc.pNext = NULL;
11050     mem_alloc.allocationSize = 0;
11051     mem_alloc.memoryTypeIndex = 0;
11052     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11053     mem_alloc.allocationSize = mem_reqs.size;
11054     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11055     ASSERT_TRUE(pass);
11056     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11057     ASSERT_VK_SUCCESS(err);
11058     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11059     ASSERT_VK_SUCCESS(err);
11060     // Now create view for image
11061     VkImageViewCreateInfo image_view_ci = {};
11062     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11063     image_view_ci.image = image;
11064     image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11065     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11066     image_view_ci.subresourceRange.layerCount = 1;
11067     image_view_ci.subresourceRange.baseArrayLayer = 0;
11068     image_view_ci.subresourceRange.levelCount = 1;
11069     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11070     VkImageView image_view;
11071     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11072     ASSERT_VK_SUCCESS(err);
11073
11074     VkDescriptorBufferInfo buff_info = {};
11075     buff_info.buffer = buffer;
11076     VkDescriptorImageInfo img_info = {};
11077     img_info.imageView = image_view;
11078     VkWriteDescriptorSet descriptor_write = {};
11079     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11080     descriptor_write.dstBinding = 0;
11081     descriptor_write.descriptorCount = 1;
11082     descriptor_write.pTexelBufferView = &buff_view;
11083     descriptor_write.pBufferInfo = &buff_info;
11084     descriptor_write.pImageInfo = &img_info;
11085
11086     // These error messages align with VkDescriptorType struct
11087     const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor
11088                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11089                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11090                                 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
11091                                 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
11092                                 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
11093                                 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11094                                 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11095                                 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11096                                 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11097                                 " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
11098     // Start loop at 1 as SAMPLER desc type has no usage bit error
11099     for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
11100         descriptor_write.descriptorType = VkDescriptorType(i);
11101         descriptor_write.dstSet = descriptor_sets[i];
11102         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]);
11103
11104         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11105
11106         m_errorMonitor->VerifyFound();
11107         vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
11108     }
11109     vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
11110     vkDestroyImage(m_device->device(), image, NULL);
11111     vkFreeMemory(m_device->device(), image_mem, NULL);
11112     vkDestroyImageView(m_device->device(), image_view, NULL);
11113     vkDestroyBuffer(m_device->device(), buffer, NULL);
11114     vkDestroyBufferView(m_device->device(), buff_view, NULL);
11115     vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
11116     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11117 }
11118
11119 TEST_F(VkLayerTest, DSBufferInfoErrors) {
11120     TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect "
11121                      "parameters in VkDescriptorBufferInfo struct. This includes:\n"
11122                      "1. offset value greater than buffer size\n"
11123                      "2. range value of 0\n"
11124                      "3. range value greater than buffer (size - offset)");
11125     VkResult err;
11126
11127     ASSERT_NO_FATAL_FAILURE(InitState());
11128     VkDescriptorPoolSize ds_type_count = {};
11129     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11130     ds_type_count.descriptorCount = 1;
11131
11132     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11133     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11134     ds_pool_ci.pNext = NULL;
11135     ds_pool_ci.maxSets = 1;
11136     ds_pool_ci.poolSizeCount = 1;
11137     ds_pool_ci.pPoolSizes = &ds_type_count;
11138
11139     VkDescriptorPool ds_pool;
11140     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11141     ASSERT_VK_SUCCESS(err);
11142
11143     // Create layout with single uniform buffer descriptor
11144     VkDescriptorSetLayoutBinding dsl_binding = {};
11145     dsl_binding.binding = 0;
11146     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11147     dsl_binding.descriptorCount = 1;
11148     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11149     dsl_binding.pImmutableSamplers = NULL;
11150
11151     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11152     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11153     ds_layout_ci.pNext = NULL;
11154     ds_layout_ci.bindingCount = 1;
11155     ds_layout_ci.pBindings = &dsl_binding;
11156     VkDescriptorSetLayout ds_layout;
11157     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11158     ASSERT_VK_SUCCESS(err);
11159
11160     VkDescriptorSet descriptor_set = {};
11161     VkDescriptorSetAllocateInfo alloc_info = {};
11162     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11163     alloc_info.descriptorSetCount = 1;
11164     alloc_info.descriptorPool = ds_pool;
11165     alloc_info.pSetLayouts = &ds_layout;
11166     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11167     ASSERT_VK_SUCCESS(err);
11168
11169     // Create a buffer to be used for invalid updates
11170     VkBufferCreateInfo buff_ci = {};
11171     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11172     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
11173     buff_ci.size = 256;
11174     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11175     VkBuffer buffer;
11176     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11177     ASSERT_VK_SUCCESS(err);
11178     // Have to bind memory to buffer before descriptor update
11179     VkMemoryAllocateInfo mem_alloc = {};
11180     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11181     mem_alloc.pNext = NULL;
11182     mem_alloc.allocationSize = 256;
11183     mem_alloc.memoryTypeIndex = 0;
11184
11185     VkMemoryRequirements mem_reqs;
11186     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
11187     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11188     if (!pass) {
11189         vkDestroyBuffer(m_device->device(), buffer, NULL);
11190         return;
11191     }
11192
11193     VkDeviceMemory mem;
11194     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
11195     ASSERT_VK_SUCCESS(err);
11196     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
11197     ASSERT_VK_SUCCESS(err);
11198
11199     VkDescriptorBufferInfo buff_info = {};
11200     buff_info.buffer = buffer;
11201     // First make offset 1 larger than buffer size
11202     buff_info.offset = 257;
11203     buff_info.range = VK_WHOLE_SIZE;
11204     VkWriteDescriptorSet descriptor_write = {};
11205     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11206     descriptor_write.dstBinding = 0;
11207     descriptor_write.descriptorCount = 1;
11208     descriptor_write.pTexelBufferView = nullptr;
11209     descriptor_write.pBufferInfo = &buff_info;
11210     descriptor_write.pImageInfo = nullptr;
11211
11212     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11213     descriptor_write.dstSet = descriptor_set;
11214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer ");
11215
11216     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11217
11218     m_errorMonitor->VerifyFound();
11219     // Now cause error due to range of 0
11220     buff_info.offset = 0;
11221     buff_info.range = 0;
11222     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11223                                          " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
11224
11225     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11226
11227     m_errorMonitor->VerifyFound();
11228     // Now cause error due to range exceeding buffer size - offset
11229     buff_info.offset = 128;
11230     buff_info.range = 200;
11231     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size ");
11232
11233     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11234
11235     m_errorMonitor->VerifyFound();
11236     vkFreeMemory(m_device->device(), mem, NULL);
11237     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11238     vkDestroyBuffer(m_device->device(), buffer, NULL);
11239     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11240     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11241 }
11242
11243 TEST_F(VkLayerTest, DSAspectBitsErrors) {
11244     // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
11245     //  are set, but could expand this test to hit more cases.
11246     TEST_DESCRIPTION("Attempt to update descriptor sets for images "
11247                      "that do not have correct aspect bits sets.");
11248     VkResult err;
11249
11250     ASSERT_NO_FATAL_FAILURE(InitState());
11251     VkDescriptorPoolSize ds_type_count = {};
11252     ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11253     ds_type_count.descriptorCount = 1;
11254
11255     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11256     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11257     ds_pool_ci.pNext = NULL;
11258     ds_pool_ci.maxSets = 5;
11259     ds_pool_ci.poolSizeCount = 1;
11260     ds_pool_ci.pPoolSizes = &ds_type_count;
11261
11262     VkDescriptorPool ds_pool;
11263     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11264     ASSERT_VK_SUCCESS(err);
11265
11266     VkDescriptorSetLayoutBinding dsl_binding = {};
11267     dsl_binding.binding = 0;
11268     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11269     dsl_binding.descriptorCount = 1;
11270     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11271     dsl_binding.pImmutableSamplers = NULL;
11272
11273     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11274     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11275     ds_layout_ci.pNext = NULL;
11276     ds_layout_ci.bindingCount = 1;
11277     ds_layout_ci.pBindings = &dsl_binding;
11278     VkDescriptorSetLayout ds_layout;
11279     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11280     ASSERT_VK_SUCCESS(err);
11281
11282     VkDescriptorSet descriptor_set = {};
11283     VkDescriptorSetAllocateInfo alloc_info = {};
11284     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11285     alloc_info.descriptorSetCount = 1;
11286     alloc_info.descriptorPool = ds_pool;
11287     alloc_info.pSetLayouts = &ds_layout;
11288     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11289     ASSERT_VK_SUCCESS(err);
11290
11291     // Create an image to be used for invalid updates
11292     VkImageCreateInfo image_ci = {};
11293     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11294     image_ci.imageType = VK_IMAGE_TYPE_2D;
11295     image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11296     image_ci.extent.width = 64;
11297     image_ci.extent.height = 64;
11298     image_ci.extent.depth = 1;
11299     image_ci.mipLevels = 1;
11300     image_ci.arrayLayers = 1;
11301     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11302     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11303     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11304     image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11305     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11306     VkImage image;
11307     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11308     ASSERT_VK_SUCCESS(err);
11309     // Bind memory to image
11310     VkMemoryRequirements mem_reqs;
11311     VkDeviceMemory image_mem;
11312     bool pass;
11313     VkMemoryAllocateInfo mem_alloc = {};
11314     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11315     mem_alloc.pNext = NULL;
11316     mem_alloc.allocationSize = 0;
11317     mem_alloc.memoryTypeIndex = 0;
11318     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11319     mem_alloc.allocationSize = mem_reqs.size;
11320     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11321     ASSERT_TRUE(pass);
11322     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11323     ASSERT_VK_SUCCESS(err);
11324     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11325     ASSERT_VK_SUCCESS(err);
11326     // Now create view for image
11327     VkImageViewCreateInfo image_view_ci = {};
11328     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11329     image_view_ci.image = image;
11330     image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11331     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11332     image_view_ci.subresourceRange.layerCount = 1;
11333     image_view_ci.subresourceRange.baseArrayLayer = 0;
11334     image_view_ci.subresourceRange.levelCount = 1;
11335     // Setting both depth & stencil aspect bits is illegal for descriptor
11336     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
11337
11338     VkImageView image_view;
11339     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11340     ASSERT_VK_SUCCESS(err);
11341
11342     VkDescriptorImageInfo img_info = {};
11343     img_info.imageView = image_view;
11344     VkWriteDescriptorSet descriptor_write = {};
11345     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11346     descriptor_write.dstBinding = 0;
11347     descriptor_write.descriptorCount = 1;
11348     descriptor_write.pTexelBufferView = NULL;
11349     descriptor_write.pBufferInfo = NULL;
11350     descriptor_write.pImageInfo = &img_info;
11351     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11352     descriptor_write.dstSet = descriptor_set;
11353     const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
11354                             "or VK_IMAGE_ASPECT_STENCIL_BIT ";
11355     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
11356
11357     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11358
11359     m_errorMonitor->VerifyFound();
11360     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11361     vkDestroyImage(m_device->device(), image, NULL);
11362     vkFreeMemory(m_device->device(), image_mem, NULL);
11363     vkDestroyImageView(m_device->device(), image_view, NULL);
11364     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11365     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11366 }
11367
11368 TEST_F(VkLayerTest, DSTypeMismatch) {
11369     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
11370     VkResult err;
11371
11372     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11373                                          " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update "
11374                                          "type is VK_DESCRIPTOR_TYPE_SAMPLER");
11375
11376     ASSERT_NO_FATAL_FAILURE(InitState());
11377     // VkDescriptorSetObj descriptorSet(m_device);
11378     VkDescriptorPoolSize ds_type_count = {};
11379     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11380     ds_type_count.descriptorCount = 1;
11381
11382     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11383     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11384     ds_pool_ci.pNext = NULL;
11385     ds_pool_ci.maxSets = 1;
11386     ds_pool_ci.poolSizeCount = 1;
11387     ds_pool_ci.pPoolSizes = &ds_type_count;
11388
11389     VkDescriptorPool ds_pool;
11390     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11391     ASSERT_VK_SUCCESS(err);
11392     VkDescriptorSetLayoutBinding dsl_binding = {};
11393     dsl_binding.binding = 0;
11394     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11395     dsl_binding.descriptorCount = 1;
11396     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11397     dsl_binding.pImmutableSamplers = NULL;
11398
11399     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11400     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11401     ds_layout_ci.pNext = NULL;
11402     ds_layout_ci.bindingCount = 1;
11403     ds_layout_ci.pBindings = &dsl_binding;
11404
11405     VkDescriptorSetLayout ds_layout;
11406     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11407     ASSERT_VK_SUCCESS(err);
11408
11409     VkDescriptorSet descriptorSet;
11410     VkDescriptorSetAllocateInfo alloc_info = {};
11411     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11412     alloc_info.descriptorSetCount = 1;
11413     alloc_info.descriptorPool = ds_pool;
11414     alloc_info.pSetLayouts = &ds_layout;
11415     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11416     ASSERT_VK_SUCCESS(err);
11417
11418     VkSamplerCreateInfo sampler_ci = {};
11419     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11420     sampler_ci.pNext = NULL;
11421     sampler_ci.magFilter = VK_FILTER_NEAREST;
11422     sampler_ci.minFilter = VK_FILTER_NEAREST;
11423     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11424     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11425     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11426     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11427     sampler_ci.mipLodBias = 1.0;
11428     sampler_ci.anisotropyEnable = VK_FALSE;
11429     sampler_ci.maxAnisotropy = 1;
11430     sampler_ci.compareEnable = VK_FALSE;
11431     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11432     sampler_ci.minLod = 1.0;
11433     sampler_ci.maxLod = 1.0;
11434     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11435     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11436     VkSampler sampler;
11437     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11438     ASSERT_VK_SUCCESS(err);
11439
11440     VkDescriptorImageInfo info = {};
11441     info.sampler = sampler;
11442
11443     VkWriteDescriptorSet descriptor_write;
11444     memset(&descriptor_write, 0, sizeof(descriptor_write));
11445     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11446     descriptor_write.dstSet = descriptorSet;
11447     descriptor_write.descriptorCount = 1;
11448     // This is a mismatched type for the layout which expects BUFFER
11449     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11450     descriptor_write.pImageInfo = &info;
11451
11452     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11453
11454     m_errorMonitor->VerifyFound();
11455
11456     vkDestroySampler(m_device->device(), sampler, NULL);
11457     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11458     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11459 }
11460
11461 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
11462     // For overlapping Update, have arrayIndex exceed that of layout
11463     VkResult err;
11464
11465     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11466                                          " binding #0 with 1 total descriptors but update of 1 descriptors "
11467                                          "starting at binding offset of 0 combined with update array element "
11468                                          "offset of 1 oversteps the size of this descriptor set.");
11469
11470     ASSERT_NO_FATAL_FAILURE(InitState());
11471     // VkDescriptorSetObj descriptorSet(m_device);
11472     VkDescriptorPoolSize ds_type_count = {};
11473     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11474     ds_type_count.descriptorCount = 1;
11475
11476     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11477     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11478     ds_pool_ci.pNext = NULL;
11479     ds_pool_ci.maxSets = 1;
11480     ds_pool_ci.poolSizeCount = 1;
11481     ds_pool_ci.pPoolSizes = &ds_type_count;
11482
11483     VkDescriptorPool ds_pool;
11484     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11485     ASSERT_VK_SUCCESS(err);
11486
11487     VkDescriptorSetLayoutBinding dsl_binding = {};
11488     dsl_binding.binding = 0;
11489     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11490     dsl_binding.descriptorCount = 1;
11491     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11492     dsl_binding.pImmutableSamplers = NULL;
11493
11494     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11495     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11496     ds_layout_ci.pNext = NULL;
11497     ds_layout_ci.bindingCount = 1;
11498     ds_layout_ci.pBindings = &dsl_binding;
11499
11500     VkDescriptorSetLayout ds_layout;
11501     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11502     ASSERT_VK_SUCCESS(err);
11503
11504     VkDescriptorSet descriptorSet;
11505     VkDescriptorSetAllocateInfo alloc_info = {};
11506     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11507     alloc_info.descriptorSetCount = 1;
11508     alloc_info.descriptorPool = ds_pool;
11509     alloc_info.pSetLayouts = &ds_layout;
11510     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11511     ASSERT_VK_SUCCESS(err);
11512
11513     // Correctly update descriptor to avoid "NOT_UPDATED" error
11514     VkDescriptorBufferInfo buff_info = {};
11515     buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test
11516     buff_info.offset = 0;
11517     buff_info.range = 1024;
11518
11519     VkWriteDescriptorSet descriptor_write;
11520     memset(&descriptor_write, 0, sizeof(descriptor_write));
11521     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11522     descriptor_write.dstSet = descriptorSet;
11523     descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
11524     descriptor_write.descriptorCount = 1;
11525     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11526     descriptor_write.pBufferInfo = &buff_info;
11527
11528     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11529
11530     m_errorMonitor->VerifyFound();
11531
11532     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11533     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11534 }
11535
11536 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
11537     // Create layout w/ count of 1 and attempt update to that layout w/ binding
11538     // index 2
11539     VkResult err;
11540
11541     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2.");
11542
11543     ASSERT_NO_FATAL_FAILURE(InitState());
11544     // VkDescriptorSetObj descriptorSet(m_device);
11545     VkDescriptorPoolSize ds_type_count = {};
11546     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11547     ds_type_count.descriptorCount = 1;
11548
11549     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11550     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11551     ds_pool_ci.pNext = NULL;
11552     ds_pool_ci.maxSets = 1;
11553     ds_pool_ci.poolSizeCount = 1;
11554     ds_pool_ci.pPoolSizes = &ds_type_count;
11555
11556     VkDescriptorPool ds_pool;
11557     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11558     ASSERT_VK_SUCCESS(err);
11559
11560     VkDescriptorSetLayoutBinding dsl_binding = {};
11561     dsl_binding.binding = 0;
11562     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11563     dsl_binding.descriptorCount = 1;
11564     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11565     dsl_binding.pImmutableSamplers = NULL;
11566
11567     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11568     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11569     ds_layout_ci.pNext = NULL;
11570     ds_layout_ci.bindingCount = 1;
11571     ds_layout_ci.pBindings = &dsl_binding;
11572     VkDescriptorSetLayout ds_layout;
11573     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11574     ASSERT_VK_SUCCESS(err);
11575
11576     VkDescriptorSet descriptorSet;
11577     VkDescriptorSetAllocateInfo alloc_info = {};
11578     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11579     alloc_info.descriptorSetCount = 1;
11580     alloc_info.descriptorPool = ds_pool;
11581     alloc_info.pSetLayouts = &ds_layout;
11582     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11583     ASSERT_VK_SUCCESS(err);
11584
11585     VkSamplerCreateInfo sampler_ci = {};
11586     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11587     sampler_ci.pNext = NULL;
11588     sampler_ci.magFilter = VK_FILTER_NEAREST;
11589     sampler_ci.minFilter = VK_FILTER_NEAREST;
11590     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11591     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11592     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11593     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11594     sampler_ci.mipLodBias = 1.0;
11595     sampler_ci.anisotropyEnable = VK_FALSE;
11596     sampler_ci.maxAnisotropy = 1;
11597     sampler_ci.compareEnable = VK_FALSE;
11598     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11599     sampler_ci.minLod = 1.0;
11600     sampler_ci.maxLod = 1.0;
11601     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11602     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11603
11604     VkSampler sampler;
11605     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11606     ASSERT_VK_SUCCESS(err);
11607
11608     VkDescriptorImageInfo info = {};
11609     info.sampler = sampler;
11610
11611     VkWriteDescriptorSet descriptor_write;
11612     memset(&descriptor_write, 0, sizeof(descriptor_write));
11613     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11614     descriptor_write.dstSet = descriptorSet;
11615     descriptor_write.dstBinding = 2;
11616     descriptor_write.descriptorCount = 1;
11617     // This is the wrong type, but out of bounds will be flagged first
11618     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11619     descriptor_write.pImageInfo = &info;
11620
11621     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11622
11623     m_errorMonitor->VerifyFound();
11624
11625     vkDestroySampler(m_device->device(), sampler, NULL);
11626     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11627     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11628 }
11629
11630 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
11631     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
11632     // types
11633     VkResult err;
11634
11635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
11636
11637     ASSERT_NO_FATAL_FAILURE(InitState());
11638
11639     VkDescriptorPoolSize ds_type_count = {};
11640     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11641     ds_type_count.descriptorCount = 1;
11642
11643     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11644     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11645     ds_pool_ci.pNext = NULL;
11646     ds_pool_ci.maxSets = 1;
11647     ds_pool_ci.poolSizeCount = 1;
11648     ds_pool_ci.pPoolSizes = &ds_type_count;
11649
11650     VkDescriptorPool ds_pool;
11651     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11652     ASSERT_VK_SUCCESS(err);
11653     VkDescriptorSetLayoutBinding dsl_binding = {};
11654     dsl_binding.binding = 0;
11655     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11656     dsl_binding.descriptorCount = 1;
11657     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11658     dsl_binding.pImmutableSamplers = NULL;
11659
11660     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11661     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11662     ds_layout_ci.pNext = NULL;
11663     ds_layout_ci.bindingCount = 1;
11664     ds_layout_ci.pBindings = &dsl_binding;
11665
11666     VkDescriptorSetLayout ds_layout;
11667     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11668     ASSERT_VK_SUCCESS(err);
11669
11670     VkDescriptorSet descriptorSet;
11671     VkDescriptorSetAllocateInfo alloc_info = {};
11672     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11673     alloc_info.descriptorSetCount = 1;
11674     alloc_info.descriptorPool = ds_pool;
11675     alloc_info.pSetLayouts = &ds_layout;
11676     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11677     ASSERT_VK_SUCCESS(err);
11678
11679     VkSamplerCreateInfo sampler_ci = {};
11680     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11681     sampler_ci.pNext = NULL;
11682     sampler_ci.magFilter = VK_FILTER_NEAREST;
11683     sampler_ci.minFilter = VK_FILTER_NEAREST;
11684     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11685     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11686     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11687     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11688     sampler_ci.mipLodBias = 1.0;
11689     sampler_ci.anisotropyEnable = VK_FALSE;
11690     sampler_ci.maxAnisotropy = 1;
11691     sampler_ci.compareEnable = VK_FALSE;
11692     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11693     sampler_ci.minLod = 1.0;
11694     sampler_ci.maxLod = 1.0;
11695     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11696     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11697     VkSampler sampler;
11698     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11699     ASSERT_VK_SUCCESS(err);
11700
11701     VkDescriptorImageInfo info = {};
11702     info.sampler = sampler;
11703
11704     VkWriteDescriptorSet descriptor_write;
11705     memset(&descriptor_write, 0, sizeof(descriptor_write));
11706     descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
11707     descriptor_write.dstSet = descriptorSet;
11708     descriptor_write.descriptorCount = 1;
11709     // This is the wrong type, but out of bounds will be flagged first
11710     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11711     descriptor_write.pImageInfo = &info;
11712
11713     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11714
11715     m_errorMonitor->VerifyFound();
11716
11717     vkDestroySampler(m_device->device(), sampler, NULL);
11718     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11719     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11720 }
11721
11722 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
11723     // Create a single Sampler descriptor and send it an invalid Sampler
11724     VkResult err;
11725
11726     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11727                                          "Attempted write update to sampler descriptor with invalid sampler");
11728
11729     ASSERT_NO_FATAL_FAILURE(InitState());
11730     // TODO : Farm Descriptor setup code to helper function(s) to reduce copied
11731     // code
11732     VkDescriptorPoolSize ds_type_count = {};
11733     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
11734     ds_type_count.descriptorCount = 1;
11735
11736     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11737     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11738     ds_pool_ci.pNext = NULL;
11739     ds_pool_ci.maxSets = 1;
11740     ds_pool_ci.poolSizeCount = 1;
11741     ds_pool_ci.pPoolSizes = &ds_type_count;
11742
11743     VkDescriptorPool ds_pool;
11744     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11745     ASSERT_VK_SUCCESS(err);
11746
11747     VkDescriptorSetLayoutBinding dsl_binding = {};
11748     dsl_binding.binding = 0;
11749     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11750     dsl_binding.descriptorCount = 1;
11751     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11752     dsl_binding.pImmutableSamplers = NULL;
11753
11754     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11755     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11756     ds_layout_ci.pNext = NULL;
11757     ds_layout_ci.bindingCount = 1;
11758     ds_layout_ci.pBindings = &dsl_binding;
11759     VkDescriptorSetLayout ds_layout;
11760     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11761     ASSERT_VK_SUCCESS(err);
11762
11763     VkDescriptorSet descriptorSet;
11764     VkDescriptorSetAllocateInfo alloc_info = {};
11765     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11766     alloc_info.descriptorSetCount = 1;
11767     alloc_info.descriptorPool = ds_pool;
11768     alloc_info.pSetLayouts = &ds_layout;
11769     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11770     ASSERT_VK_SUCCESS(err);
11771
11772     VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle
11773
11774     VkDescriptorImageInfo descriptor_info;
11775     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11776     descriptor_info.sampler = sampler;
11777
11778     VkWriteDescriptorSet descriptor_write;
11779     memset(&descriptor_write, 0, sizeof(descriptor_write));
11780     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11781     descriptor_write.dstSet = descriptorSet;
11782     descriptor_write.dstBinding = 0;
11783     descriptor_write.descriptorCount = 1;
11784     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11785     descriptor_write.pImageInfo = &descriptor_info;
11786
11787     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11788
11789     m_errorMonitor->VerifyFound();
11790
11791     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11792     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11793 }
11794
11795 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
11796     // Create a single combined Image/Sampler descriptor and send it an invalid
11797     // imageView
11798     VkResult err;
11799
11800     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined "
11801                                                                         "image sampler descriptor failed due "
11802                                                                         "to: Invalid VkImageView:");
11803
11804     ASSERT_NO_FATAL_FAILURE(InitState());
11805     VkDescriptorPoolSize ds_type_count = {};
11806     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11807     ds_type_count.descriptorCount = 1;
11808
11809     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11810     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11811     ds_pool_ci.pNext = NULL;
11812     ds_pool_ci.maxSets = 1;
11813     ds_pool_ci.poolSizeCount = 1;
11814     ds_pool_ci.pPoolSizes = &ds_type_count;
11815
11816     VkDescriptorPool ds_pool;
11817     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11818     ASSERT_VK_SUCCESS(err);
11819
11820     VkDescriptorSetLayoutBinding dsl_binding = {};
11821     dsl_binding.binding = 0;
11822     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11823     dsl_binding.descriptorCount = 1;
11824     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11825     dsl_binding.pImmutableSamplers = NULL;
11826
11827     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11828     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11829     ds_layout_ci.pNext = NULL;
11830     ds_layout_ci.bindingCount = 1;
11831     ds_layout_ci.pBindings = &dsl_binding;
11832     VkDescriptorSetLayout ds_layout;
11833     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11834     ASSERT_VK_SUCCESS(err);
11835
11836     VkDescriptorSet descriptorSet;
11837     VkDescriptorSetAllocateInfo alloc_info = {};
11838     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11839     alloc_info.descriptorSetCount = 1;
11840     alloc_info.descriptorPool = ds_pool;
11841     alloc_info.pSetLayouts = &ds_layout;
11842     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11843     ASSERT_VK_SUCCESS(err);
11844
11845     VkSamplerCreateInfo sampler_ci = {};
11846     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11847     sampler_ci.pNext = NULL;
11848     sampler_ci.magFilter = VK_FILTER_NEAREST;
11849     sampler_ci.minFilter = VK_FILTER_NEAREST;
11850     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11851     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11852     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11853     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11854     sampler_ci.mipLodBias = 1.0;
11855     sampler_ci.anisotropyEnable = VK_FALSE;
11856     sampler_ci.maxAnisotropy = 1;
11857     sampler_ci.compareEnable = VK_FALSE;
11858     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11859     sampler_ci.minLod = 1.0;
11860     sampler_ci.maxLod = 1.0;
11861     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11862     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11863
11864     VkSampler sampler;
11865     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11866     ASSERT_VK_SUCCESS(err);
11867
11868     VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object
11869
11870     VkDescriptorImageInfo descriptor_info;
11871     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11872     descriptor_info.sampler = sampler;
11873     descriptor_info.imageView = view;
11874
11875     VkWriteDescriptorSet descriptor_write;
11876     memset(&descriptor_write, 0, sizeof(descriptor_write));
11877     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11878     descriptor_write.dstSet = descriptorSet;
11879     descriptor_write.dstBinding = 0;
11880     descriptor_write.descriptorCount = 1;
11881     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11882     descriptor_write.pImageInfo = &descriptor_info;
11883
11884     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11885
11886     m_errorMonitor->VerifyFound();
11887
11888     vkDestroySampler(m_device->device(), sampler, NULL);
11889     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11890     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11891 }
11892
11893 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
11894     // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
11895     // into the other
11896     VkResult err;
11897
11898     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type "
11899                                                                         "VK_DESCRIPTOR_TYPE_SAMPLER. Types do "
11900                                                                         "not match.");
11901
11902     ASSERT_NO_FATAL_FAILURE(InitState());
11903     // VkDescriptorSetObj descriptorSet(m_device);
11904     VkDescriptorPoolSize ds_type_count[2] = {};
11905     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11906     ds_type_count[0].descriptorCount = 1;
11907     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
11908     ds_type_count[1].descriptorCount = 1;
11909
11910     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11911     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11912     ds_pool_ci.pNext = NULL;
11913     ds_pool_ci.maxSets = 1;
11914     ds_pool_ci.poolSizeCount = 2;
11915     ds_pool_ci.pPoolSizes = ds_type_count;
11916
11917     VkDescriptorPool ds_pool;
11918     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11919     ASSERT_VK_SUCCESS(err);
11920     VkDescriptorSetLayoutBinding dsl_binding[2] = {};
11921     dsl_binding[0].binding = 0;
11922     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11923     dsl_binding[0].descriptorCount = 1;
11924     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
11925     dsl_binding[0].pImmutableSamplers = NULL;
11926     dsl_binding[1].binding = 1;
11927     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11928     dsl_binding[1].descriptorCount = 1;
11929     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
11930     dsl_binding[1].pImmutableSamplers = NULL;
11931
11932     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11933     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11934     ds_layout_ci.pNext = NULL;
11935     ds_layout_ci.bindingCount = 2;
11936     ds_layout_ci.pBindings = dsl_binding;
11937
11938     VkDescriptorSetLayout ds_layout;
11939     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11940     ASSERT_VK_SUCCESS(err);
11941
11942     VkDescriptorSet descriptorSet;
11943     VkDescriptorSetAllocateInfo alloc_info = {};
11944     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11945     alloc_info.descriptorSetCount = 1;
11946     alloc_info.descriptorPool = ds_pool;
11947     alloc_info.pSetLayouts = &ds_layout;
11948     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11949     ASSERT_VK_SUCCESS(err);
11950
11951     VkSamplerCreateInfo sampler_ci = {};
11952     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11953     sampler_ci.pNext = NULL;
11954     sampler_ci.magFilter = VK_FILTER_NEAREST;
11955     sampler_ci.minFilter = VK_FILTER_NEAREST;
11956     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11957     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11958     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11959     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11960     sampler_ci.mipLodBias = 1.0;
11961     sampler_ci.anisotropyEnable = VK_FALSE;
11962     sampler_ci.maxAnisotropy = 1;
11963     sampler_ci.compareEnable = VK_FALSE;
11964     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11965     sampler_ci.minLod = 1.0;
11966     sampler_ci.maxLod = 1.0;
11967     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11968     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11969
11970     VkSampler sampler;
11971     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11972     ASSERT_VK_SUCCESS(err);
11973
11974     VkDescriptorImageInfo info = {};
11975     info.sampler = sampler;
11976
11977     VkWriteDescriptorSet descriptor_write;
11978     memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
11979     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11980     descriptor_write.dstSet = descriptorSet;
11981     descriptor_write.dstBinding = 1; // SAMPLER binding from layout above
11982     descriptor_write.descriptorCount = 1;
11983     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11984     descriptor_write.pImageInfo = &info;
11985     // This write update should succeed
11986     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11987     // Now perform a copy update that fails due to type mismatch
11988     VkCopyDescriptorSet copy_ds_update;
11989     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
11990     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
11991     copy_ds_update.srcSet = descriptorSet;
11992     copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding
11993     copy_ds_update.dstSet = descriptorSet;
11994     copy_ds_update.dstBinding = 0;      // ERROR : copy to UNIFORM binding
11995     copy_ds_update.descriptorCount = 1; // copy 1 descriptor
11996     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
11997
11998     m_errorMonitor->VerifyFound();
11999     // Now perform a copy update that fails due to binding out of bounds
12000     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
12001     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12002     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12003     copy_ds_update.srcSet = descriptorSet;
12004     copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout
12005     copy_ds_update.dstSet = descriptorSet;
12006     copy_ds_update.dstBinding = 0;
12007     copy_ds_update.descriptorCount = 1; // Copy 1 descriptor
12008     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12009
12010     m_errorMonitor->VerifyFound();
12011
12012     // Now perform a copy update that fails due to binding out of bounds
12013     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus "
12014                                                                         "update array offset of 0 and update of "
12015                                                                         "5 descriptors oversteps total number "
12016                                                                         "of descriptors in set: 2.");
12017
12018     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12019     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12020     copy_ds_update.srcSet = descriptorSet;
12021     copy_ds_update.srcBinding = 1;
12022     copy_ds_update.dstSet = descriptorSet;
12023     copy_ds_update.dstBinding = 0;
12024     copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout)
12025     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12026
12027     m_errorMonitor->VerifyFound();
12028
12029     vkDestroySampler(m_device->device(), sampler, NULL);
12030     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12031     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12032 }
12033
12034 TEST_F(VkLayerTest, NumSamplesMismatch) {
12035     // Create CommandBuffer where MSAA samples doesn't match RenderPass
12036     // sampleCount
12037     VkResult err;
12038
12039     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
12040
12041     ASSERT_NO_FATAL_FAILURE(InitState());
12042     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12043     VkDescriptorPoolSize ds_type_count = {};
12044     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12045     ds_type_count.descriptorCount = 1;
12046
12047     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12048     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12049     ds_pool_ci.pNext = NULL;
12050     ds_pool_ci.maxSets = 1;
12051     ds_pool_ci.poolSizeCount = 1;
12052     ds_pool_ci.pPoolSizes = &ds_type_count;
12053
12054     VkDescriptorPool ds_pool;
12055     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12056     ASSERT_VK_SUCCESS(err);
12057
12058     VkDescriptorSetLayoutBinding dsl_binding = {};
12059     dsl_binding.binding = 0;
12060     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12061     dsl_binding.descriptorCount = 1;
12062     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12063     dsl_binding.pImmutableSamplers = NULL;
12064
12065     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12066     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12067     ds_layout_ci.pNext = NULL;
12068     ds_layout_ci.bindingCount = 1;
12069     ds_layout_ci.pBindings = &dsl_binding;
12070
12071     VkDescriptorSetLayout ds_layout;
12072     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12073     ASSERT_VK_SUCCESS(err);
12074
12075     VkDescriptorSet descriptorSet;
12076     VkDescriptorSetAllocateInfo alloc_info = {};
12077     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12078     alloc_info.descriptorSetCount = 1;
12079     alloc_info.descriptorPool = ds_pool;
12080     alloc_info.pSetLayouts = &ds_layout;
12081     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12082     ASSERT_VK_SUCCESS(err);
12083
12084     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12085     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12086     pipe_ms_state_ci.pNext = NULL;
12087     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12088     pipe_ms_state_ci.sampleShadingEnable = 0;
12089     pipe_ms_state_ci.minSampleShading = 1.0;
12090     pipe_ms_state_ci.pSampleMask = NULL;
12091
12092     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12093     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12094     pipeline_layout_ci.pNext = NULL;
12095     pipeline_layout_ci.setLayoutCount = 1;
12096     pipeline_layout_ci.pSetLayouts = &ds_layout;
12097
12098     VkPipelineLayout pipeline_layout;
12099     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12100     ASSERT_VK_SUCCESS(err);
12101
12102     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12103     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12104     // but add it to be able to run on more devices
12105     VkPipelineObj pipe(m_device);
12106     pipe.AddShader(&vs);
12107     pipe.AddShader(&fs);
12108     pipe.AddColorAttachment();
12109     pipe.SetMSAA(&pipe_ms_state_ci);
12110     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12111
12112     BeginCommandBuffer();
12113     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12114
12115     // Render triangle (the error should trigger on the attempt to draw).
12116     Draw(3, 1, 0, 0);
12117
12118     // Finalize recording of the command buffer
12119     EndCommandBuffer();
12120
12121     m_errorMonitor->VerifyFound();
12122
12123     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12124     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12125     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12126 }
12127
12128 TEST_F(VkLayerTest, RenderPassIncompatible) {
12129     TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
12130                      "Initial case is drawing with an active renderpass that's "
12131                      "not compatible with the bound PSO's creation renderpass");
12132     VkResult err;
12133
12134     ASSERT_NO_FATAL_FAILURE(InitState());
12135     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12136
12137     VkDescriptorSetLayoutBinding dsl_binding = {};
12138     dsl_binding.binding = 0;
12139     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12140     dsl_binding.descriptorCount = 1;
12141     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12142     dsl_binding.pImmutableSamplers = NULL;
12143
12144     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12145     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12146     ds_layout_ci.pNext = NULL;
12147     ds_layout_ci.bindingCount = 1;
12148     ds_layout_ci.pBindings = &dsl_binding;
12149
12150     VkDescriptorSetLayout ds_layout;
12151     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12152     ASSERT_VK_SUCCESS(err);
12153
12154     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12155     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12156     pipeline_layout_ci.pNext = NULL;
12157     pipeline_layout_ci.setLayoutCount = 1;
12158     pipeline_layout_ci.pSetLayouts = &ds_layout;
12159
12160     VkPipelineLayout pipeline_layout;
12161     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12162     ASSERT_VK_SUCCESS(err);
12163
12164     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12165     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12166     // but add it to be able to run on more devices
12167     // Create a renderpass that will be incompatible with default renderpass
12168     VkAttachmentReference attach = {};
12169     attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12170     VkAttachmentReference color_att = {};
12171     color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12172     VkSubpassDescription subpass = {};
12173     subpass.inputAttachmentCount = 1;
12174     subpass.pInputAttachments = &attach;
12175     subpass.colorAttachmentCount = 1;
12176     subpass.pColorAttachments = &color_att;
12177     VkRenderPassCreateInfo rpci = {};
12178     rpci.subpassCount = 1;
12179     rpci.pSubpasses = &subpass;
12180     rpci.attachmentCount = 1;
12181     VkAttachmentDescription attach_desc = {};
12182     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12183     // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
12184     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
12185     rpci.pAttachments = &attach_desc;
12186     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12187     VkRenderPass rp;
12188     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12189     VkPipelineObj pipe(m_device);
12190     pipe.AddShader(&vs);
12191     pipe.AddShader(&fs);
12192     pipe.AddColorAttachment();
12193     VkViewport view_port = {};
12194     m_viewports.push_back(view_port);
12195     pipe.SetViewport(m_viewports);
12196     VkRect2D rect = {};
12197     m_scissors.push_back(rect);
12198     pipe.SetScissor(m_scissors);
12199     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12200
12201     VkCommandBufferInheritanceInfo cbii = {};
12202     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12203     cbii.renderPass = rp;
12204     cbii.subpass = 0;
12205     VkCommandBufferBeginInfo cbbi = {};
12206     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12207     cbbi.pInheritanceInfo = &cbii;
12208     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
12209     VkRenderPassBeginInfo rpbi = {};
12210     rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
12211     rpbi.framebuffer = m_framebuffer;
12212     rpbi.renderPass = rp;
12213     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
12214     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12215
12216     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline ");
12217     // Render triangle (the error should trigger on the attempt to draw).
12218     Draw(3, 1, 0, 0);
12219
12220     // Finalize recording of the command buffer
12221     EndCommandBuffer();
12222
12223     m_errorMonitor->VerifyFound();
12224
12225     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12226     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12227     vkDestroyRenderPass(m_device->device(), rp, NULL);
12228 }
12229
12230 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
12231     // Create Pipeline where the number of blend attachments doesn't match the
12232     // number of color attachments.  In this case, we don't add any color
12233     // blend attachments even though we have a color attachment.
12234     VkResult err;
12235
12236     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12237                                          "Render pass subpass 0 mismatch with blending state defined and blend state attachment");
12238
12239     ASSERT_NO_FATAL_FAILURE(InitState());
12240     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12241     VkDescriptorPoolSize ds_type_count = {};
12242     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12243     ds_type_count.descriptorCount = 1;
12244
12245     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12246     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12247     ds_pool_ci.pNext = NULL;
12248     ds_pool_ci.maxSets = 1;
12249     ds_pool_ci.poolSizeCount = 1;
12250     ds_pool_ci.pPoolSizes = &ds_type_count;
12251
12252     VkDescriptorPool ds_pool;
12253     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12254     ASSERT_VK_SUCCESS(err);
12255
12256     VkDescriptorSetLayoutBinding dsl_binding = {};
12257     dsl_binding.binding = 0;
12258     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12259     dsl_binding.descriptorCount = 1;
12260     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12261     dsl_binding.pImmutableSamplers = NULL;
12262
12263     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12264     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12265     ds_layout_ci.pNext = NULL;
12266     ds_layout_ci.bindingCount = 1;
12267     ds_layout_ci.pBindings = &dsl_binding;
12268
12269     VkDescriptorSetLayout ds_layout;
12270     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12271     ASSERT_VK_SUCCESS(err);
12272
12273     VkDescriptorSet descriptorSet;
12274     VkDescriptorSetAllocateInfo alloc_info = {};
12275     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12276     alloc_info.descriptorSetCount = 1;
12277     alloc_info.descriptorPool = ds_pool;
12278     alloc_info.pSetLayouts = &ds_layout;
12279     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12280     ASSERT_VK_SUCCESS(err);
12281
12282     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12283     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12284     pipe_ms_state_ci.pNext = NULL;
12285     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12286     pipe_ms_state_ci.sampleShadingEnable = 0;
12287     pipe_ms_state_ci.minSampleShading = 1.0;
12288     pipe_ms_state_ci.pSampleMask = NULL;
12289
12290     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12291     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12292     pipeline_layout_ci.pNext = NULL;
12293     pipeline_layout_ci.setLayoutCount = 1;
12294     pipeline_layout_ci.pSetLayouts = &ds_layout;
12295
12296     VkPipelineLayout pipeline_layout;
12297     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12298     ASSERT_VK_SUCCESS(err);
12299
12300     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12301     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12302     // but add it to be able to run on more devices
12303     VkPipelineObj pipe(m_device);
12304     pipe.AddShader(&vs);
12305     pipe.AddShader(&fs);
12306     pipe.SetMSAA(&pipe_ms_state_ci);
12307     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12308
12309     BeginCommandBuffer();
12310     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12311
12312     // Render triangle (the error should trigger on the attempt to draw).
12313     Draw(3, 1, 0, 0);
12314
12315     // Finalize recording of the command buffer
12316     EndCommandBuffer();
12317
12318     m_errorMonitor->VerifyFound();
12319
12320     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12321     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12322     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12323 }
12324
12325 TEST_F(VkLayerTest, MissingClearAttachment) {
12326     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
12327                      "structure passed to vkCmdClearAttachments");
12328     ASSERT_NO_FATAL_FAILURE(InitState());
12329     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12330                                          "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored");
12331
12332     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
12333     m_errorMonitor->VerifyFound();
12334 }
12335
12336 TEST_F(VkLayerTest, ClearCmdNoDraw) {
12337     // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
12338     // to issuing a Draw
12339     VkResult err;
12340
12341     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12342                                          "vkCmdClearAttachments() issued on CB object ");
12343
12344     ASSERT_NO_FATAL_FAILURE(InitState());
12345     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12346
12347     VkDescriptorPoolSize ds_type_count = {};
12348     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12349     ds_type_count.descriptorCount = 1;
12350
12351     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12352     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12353     ds_pool_ci.pNext = NULL;
12354     ds_pool_ci.maxSets = 1;
12355     ds_pool_ci.poolSizeCount = 1;
12356     ds_pool_ci.pPoolSizes = &ds_type_count;
12357
12358     VkDescriptorPool ds_pool;
12359     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12360     ASSERT_VK_SUCCESS(err);
12361
12362     VkDescriptorSetLayoutBinding dsl_binding = {};
12363     dsl_binding.binding = 0;
12364     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12365     dsl_binding.descriptorCount = 1;
12366     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12367     dsl_binding.pImmutableSamplers = NULL;
12368
12369     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12370     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12371     ds_layout_ci.pNext = NULL;
12372     ds_layout_ci.bindingCount = 1;
12373     ds_layout_ci.pBindings = &dsl_binding;
12374
12375     VkDescriptorSetLayout ds_layout;
12376     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12377     ASSERT_VK_SUCCESS(err);
12378
12379     VkDescriptorSet descriptorSet;
12380     VkDescriptorSetAllocateInfo alloc_info = {};
12381     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12382     alloc_info.descriptorSetCount = 1;
12383     alloc_info.descriptorPool = ds_pool;
12384     alloc_info.pSetLayouts = &ds_layout;
12385     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12386     ASSERT_VK_SUCCESS(err);
12387
12388     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12389     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12390     pipe_ms_state_ci.pNext = NULL;
12391     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12392     pipe_ms_state_ci.sampleShadingEnable = 0;
12393     pipe_ms_state_ci.minSampleShading = 1.0;
12394     pipe_ms_state_ci.pSampleMask = NULL;
12395
12396     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12397     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12398     pipeline_layout_ci.pNext = NULL;
12399     pipeline_layout_ci.setLayoutCount = 1;
12400     pipeline_layout_ci.pSetLayouts = &ds_layout;
12401
12402     VkPipelineLayout pipeline_layout;
12403     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12404     ASSERT_VK_SUCCESS(err);
12405
12406     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12407     //  We shouldn't need a fragment shader but add it to be able to run
12408     //  on more devices
12409     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12410
12411     VkPipelineObj pipe(m_device);
12412     pipe.AddShader(&vs);
12413     pipe.AddShader(&fs);
12414     pipe.SetMSAA(&pipe_ms_state_ci);
12415     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12416
12417     BeginCommandBuffer();
12418
12419     // Main thing we care about for this test is that the VkImage obj we're
12420     // clearing matches Color Attachment of FB
12421     //  Also pass down other dummy params to keep driver and paramchecker happy
12422     VkClearAttachment color_attachment;
12423     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12424     color_attachment.clearValue.color.float32[0] = 1.0;
12425     color_attachment.clearValue.color.float32[1] = 1.0;
12426     color_attachment.clearValue.color.float32[2] = 1.0;
12427     color_attachment.clearValue.color.float32[3] = 1.0;
12428     color_attachment.colorAttachment = 0;
12429     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}};
12430
12431     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
12432
12433     m_errorMonitor->VerifyFound();
12434
12435     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12436     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12437     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12438 }
12439
12440 TEST_F(VkLayerTest, VtxBufferBadIndex) {
12441     VkResult err;
12442
12443     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12444                                          "but no vertex buffers are attached to this Pipeline State Object");
12445
12446     ASSERT_NO_FATAL_FAILURE(InitState());
12447     ASSERT_NO_FATAL_FAILURE(InitViewport());
12448     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12449
12450     VkDescriptorPoolSize ds_type_count = {};
12451     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12452     ds_type_count.descriptorCount = 1;
12453
12454     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12455     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12456     ds_pool_ci.pNext = NULL;
12457     ds_pool_ci.maxSets = 1;
12458     ds_pool_ci.poolSizeCount = 1;
12459     ds_pool_ci.pPoolSizes = &ds_type_count;
12460
12461     VkDescriptorPool ds_pool;
12462     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12463     ASSERT_VK_SUCCESS(err);
12464
12465     VkDescriptorSetLayoutBinding dsl_binding = {};
12466     dsl_binding.binding = 0;
12467     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12468     dsl_binding.descriptorCount = 1;
12469     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12470     dsl_binding.pImmutableSamplers = NULL;
12471
12472     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12473     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12474     ds_layout_ci.pNext = NULL;
12475     ds_layout_ci.bindingCount = 1;
12476     ds_layout_ci.pBindings = &dsl_binding;
12477
12478     VkDescriptorSetLayout ds_layout;
12479     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12480     ASSERT_VK_SUCCESS(err);
12481
12482     VkDescriptorSet descriptorSet;
12483     VkDescriptorSetAllocateInfo alloc_info = {};
12484     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12485     alloc_info.descriptorSetCount = 1;
12486     alloc_info.descriptorPool = ds_pool;
12487     alloc_info.pSetLayouts = &ds_layout;
12488     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12489     ASSERT_VK_SUCCESS(err);
12490
12491     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12492     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12493     pipe_ms_state_ci.pNext = NULL;
12494     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12495     pipe_ms_state_ci.sampleShadingEnable = 0;
12496     pipe_ms_state_ci.minSampleShading = 1.0;
12497     pipe_ms_state_ci.pSampleMask = NULL;
12498
12499     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12500     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12501     pipeline_layout_ci.pNext = NULL;
12502     pipeline_layout_ci.setLayoutCount = 1;
12503     pipeline_layout_ci.pSetLayouts = &ds_layout;
12504     VkPipelineLayout pipeline_layout;
12505
12506     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12507     ASSERT_VK_SUCCESS(err);
12508
12509     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12510     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12511     // but add it to be able to run on more devices
12512     VkPipelineObj pipe(m_device);
12513     pipe.AddShader(&vs);
12514     pipe.AddShader(&fs);
12515     pipe.AddColorAttachment();
12516     pipe.SetMSAA(&pipe_ms_state_ci);
12517     pipe.SetViewport(m_viewports);
12518     pipe.SetScissor(m_scissors);
12519     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12520
12521     BeginCommandBuffer();
12522     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12523     // Don't care about actual data, just need to get to draw to flag error
12524     static const float vbo_data[3] = {1.f, 0.f, 1.f};
12525     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data);
12526     BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
12527     Draw(1, 0, 0, 0);
12528
12529     m_errorMonitor->VerifyFound();
12530
12531     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12532     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12533     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12534 }
12535
12536 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
12537     TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call."
12538                      "Use invalid Queue Family Index in vkCreateDevice");
12539     ASSERT_NO_FATAL_FAILURE(InitState());
12540
12541     const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() "
12542                                          "w/ pPhysicalDeviceCount value ";
12543
12544     const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid "
12545                                                    "queueFamilyIndex ";
12546
12547     const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #";
12548
12549     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message);
12550     // The following test fails with recent NVidia drivers.
12551     // By the time core_validation is reached, the NVidia
12552     // driver has sanitized the invalid condition and core_validation
12553     // is not introduced to the failure condition. This is not the case
12554     // with AMD and Mesa drivers. Futher investigation is required
12555     //    uint32_t count = static_cast<uint32_t>(~0);
12556     //    VkPhysicalDevice physical_device;
12557     //    vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
12558     //    m_errorMonitor->VerifyFound();
12559
12560     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message);
12561     float queue_priority = 0.0;
12562
12563     VkDeviceQueueCreateInfo queue_create_info = {};
12564     queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
12565     queue_create_info.queueCount = 1;
12566     queue_create_info.pQueuePriorities = &queue_priority;
12567     queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
12568
12569     VkPhysicalDeviceFeatures features = m_device->phy().features();
12570     VkDevice testDevice;
12571     VkDeviceCreateInfo device_create_info = {};
12572     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
12573     device_create_info.queueCreateInfoCount = 1;
12574     device_create_info.pQueueCreateInfos = &queue_create_info;
12575     device_create_info.pEnabledFeatures = &features;
12576     vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12577     m_errorMonitor->VerifyFound();
12578
12579     queue_create_info.queueFamilyIndex = 1;
12580
12581     unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
12582     VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
12583     for (unsigned i = 0; i < feature_count; i++) {
12584         if (VK_FALSE == feature_array[i]) {
12585             feature_array[i] = VK_TRUE;
12586             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message);
12587             device_create_info.pEnabledFeatures = &features;
12588             vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12589             m_errorMonitor->VerifyFound();
12590             break;
12591         }
12592     }
12593 }
12594
12595 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) {
12596     TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call."
12597                      "End a command buffer with a query still in progress.");
12598
12599     const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one "
12600                                       "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both "
12601                                       "must be.";
12602
12603     const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
12604
12605     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index);
12606
12607     ASSERT_NO_FATAL_FAILURE(InitState());
12608
12609     VkEvent event;
12610     VkEventCreateInfo event_create_info{};
12611     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12612     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12613
12614     VkQueue queue = VK_NULL_HANDLE;
12615     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
12616
12617     BeginCommandBuffer();
12618
12619     VkImageObj image(m_device);
12620     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12621     ASSERT_TRUE(image.initialized());
12622     VkImageMemoryBarrier img_barrier = {};
12623     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
12624     img_barrier.pNext = NULL;
12625     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
12626     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
12627     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12628     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12629     img_barrier.image = image.handle();
12630     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
12631
12632     // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies
12633     // that layer validation catches the case when it is not.
12634     img_barrier.dstQueueFamilyIndex = 0;
12635     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12636     img_barrier.subresourceRange.baseArrayLayer = 0;
12637     img_barrier.subresourceRange.baseMipLevel = 0;
12638     img_barrier.subresourceRange.layerCount = 1;
12639     img_barrier.subresourceRange.levelCount = 1;
12640     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
12641                     nullptr, 0, nullptr, 1, &img_barrier);
12642     m_errorMonitor->VerifyFound();
12643
12644     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
12645
12646     VkQueryPool query_pool;
12647     VkQueryPoolCreateInfo query_pool_create_info = {};
12648     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
12649     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
12650     query_pool_create_info.queryCount = 1;
12651     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12652
12653     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
12654     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12655
12656     vkEndCommandBuffer(m_commandBuffer->handle());
12657     m_errorMonitor->VerifyFound();
12658
12659     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
12660     vkDestroyEvent(m_device->device(), event, nullptr);
12661 }
12662
12663 TEST_F(VkLayerTest, VertexBufferInvalid) {
12664     TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
12665                      "delete a buffer twice, use an invalid offset for each "
12666                      "buffer type, and attempt to bind a null buffer");
12667
12668     const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
12669                                                    "using deleted buffer ";
12670     const char *double_destroy_message = "Cannot free buffer 0x";
12671     const char *invalid_offset_message = "vkBindBufferMemory(): "
12672                                          "memoryOffset is 0x";
12673     const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
12674                                                         "storage memoryOffset "
12675                                                         "is 0x";
12676     const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
12677                                                       "texel memoryOffset "
12678                                                       "is 0x";
12679     const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
12680                                                         "uniform memoryOffset "
12681                                                         "is 0x";
12682     const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
12683                                            " to Bind Obj(0x";
12684     const char *free_invalid_buffer_message = "Request to delete memory "
12685                                               "object 0x";
12686
12687     ASSERT_NO_FATAL_FAILURE(InitState());
12688     ASSERT_NO_FATAL_FAILURE(InitViewport());
12689     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12690
12691     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12692     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12693     pipe_ms_state_ci.pNext = NULL;
12694     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12695     pipe_ms_state_ci.sampleShadingEnable = 0;
12696     pipe_ms_state_ci.minSampleShading = 1.0;
12697     pipe_ms_state_ci.pSampleMask = nullptr;
12698
12699     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12700     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12701     VkPipelineLayout pipeline_layout;
12702
12703     VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout);
12704     ASSERT_VK_SUCCESS(err);
12705
12706     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12707     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12708     VkPipelineObj pipe(m_device);
12709     pipe.AddShader(&vs);
12710     pipe.AddShader(&fs);
12711     pipe.AddColorAttachment();
12712     pipe.SetMSAA(&pipe_ms_state_ci);
12713     pipe.SetViewport(m_viewports);
12714     pipe.SetScissor(m_scissors);
12715     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12716
12717     BeginCommandBuffer();
12718     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12719
12720     {
12721         // Create and bind a vertex buffer in a reduced scope, which will cause
12722         // it to be deleted upon leaving this scope
12723         const float vbo_data[3] = {1.f, 0.f, 1.f};
12724         VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data);
12725         draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
12726         draw_verticies.AddVertexInputToPipe(pipe);
12727     }
12728
12729     Draw(1, 0, 0, 0);
12730
12731     EndCommandBuffer();
12732
12733     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
12734     QueueCommandBuffer(false);
12735     m_errorMonitor->VerifyFound();
12736
12737     {
12738         // Create and bind a vertex buffer in a reduced scope, and delete it
12739         // twice, the second through the destructor
12740         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
12741         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message);
12742         buffer_test.TestDoubleDestroy();
12743     }
12744     m_errorMonitor->VerifyFound();
12745
12746     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
12747         // Create and bind a memory buffer with an invalid offset.
12748         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
12749         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
12750         (void)buffer_test;
12751         m_errorMonitor->VerifyFound();
12752     }
12753
12754     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
12755                                             VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
12756         // Create and bind a memory buffer with an invalid offset again,
12757         // but look for a texel buffer message.
12758         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
12759         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12760         (void)buffer_test;
12761         m_errorMonitor->VerifyFound();
12762     }
12763
12764     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
12765         // Create and bind a memory buffer with an invalid offset again, but
12766         // look for a uniform buffer message.
12767         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
12768         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12769         (void)buffer_test;
12770         m_errorMonitor->VerifyFound();
12771     }
12772
12773     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
12774         // Create and bind a memory buffer with an invalid offset again, but
12775         // look for a storage buffer message.
12776         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
12777         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12778         (void)buffer_test;
12779         m_errorMonitor->VerifyFound();
12780     }
12781
12782     {
12783         // Attempt to bind a null buffer.
12784         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message);
12785         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer);
12786         (void)buffer_test;
12787         m_errorMonitor->VerifyFound();
12788     }
12789
12790     {
12791         // Attempt to use an invalid handle to delete a buffer.
12792         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message);
12793         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
12794         (void)buffer_test;
12795     }
12796     m_errorMonitor->VerifyFound();
12797
12798     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12799 }
12800
12801 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
12802 TEST_F(VkLayerTest, InvalidImageLayout) {
12803     TEST_DESCRIPTION("Hit all possible validation checks associated with the "
12804                      "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having"
12805                      "images in the wrong layout when they're copied or transitioned.");
12806     // 3 in ValidateCmdBufImageLayouts
12807     // *  -1 Attempt to submit cmd buf w/ deleted image
12808     // *  -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
12809     // *  -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
12810     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12811                                          "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
12812
12813     ASSERT_NO_FATAL_FAILURE(InitState());
12814     // Create src & dst images to use for copy operations
12815     VkImage src_image;
12816     VkImage dst_image;
12817
12818     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
12819     const int32_t tex_width = 32;
12820     const int32_t tex_height = 32;
12821
12822     VkImageCreateInfo image_create_info = {};
12823     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
12824     image_create_info.pNext = NULL;
12825     image_create_info.imageType = VK_IMAGE_TYPE_2D;
12826     image_create_info.format = tex_format;
12827     image_create_info.extent.width = tex_width;
12828     image_create_info.extent.height = tex_height;
12829     image_create_info.extent.depth = 1;
12830     image_create_info.mipLevels = 1;
12831     image_create_info.arrayLayers = 4;
12832     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
12833     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
12834     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
12835     image_create_info.flags = 0;
12836
12837     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
12838     ASSERT_VK_SUCCESS(err);
12839     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
12840     ASSERT_VK_SUCCESS(err);
12841
12842     BeginCommandBuffer();
12843     VkImageCopy copyRegion;
12844     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12845     copyRegion.srcSubresource.mipLevel = 0;
12846     copyRegion.srcSubresource.baseArrayLayer = 0;
12847     copyRegion.srcSubresource.layerCount = 1;
12848     copyRegion.srcOffset.x = 0;
12849     copyRegion.srcOffset.y = 0;
12850     copyRegion.srcOffset.z = 0;
12851     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12852     copyRegion.dstSubresource.mipLevel = 0;
12853     copyRegion.dstSubresource.baseArrayLayer = 0;
12854     copyRegion.dstSubresource.layerCount = 1;
12855     copyRegion.dstOffset.x = 0;
12856     copyRegion.dstOffset.y = 0;
12857     copyRegion.dstOffset.z = 0;
12858     copyRegion.extent.width = 1;
12859     copyRegion.extent.height = 1;
12860     copyRegion.extent.depth = 1;
12861     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12862     m_errorMonitor->VerifyFound();
12863     // Now cause error due to src image layout changing
12864     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is "
12865                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12866                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12867     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12868     m_errorMonitor->VerifyFound();
12869     // Final src error is due to bad layout type
12870     m_errorMonitor->SetDesiredFailureMsg(
12871         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12872         "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL.");
12873     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12874     m_errorMonitor->VerifyFound();
12875     // Now verify same checks for dst
12876     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12877                                          "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
12878     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12879     m_errorMonitor->VerifyFound();
12880     // Now cause error due to src image layout changing
12881     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is "
12882                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12883                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12884     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12885     m_errorMonitor->VerifyFound();
12886     m_errorMonitor->SetDesiredFailureMsg(
12887         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12888         "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL.");
12889     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12890     m_errorMonitor->VerifyFound();
12891     // Now cause error due to bad image layout transition in PipelineBarrier
12892     VkImageMemoryBarrier image_barrier[1] = {};
12893     image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12894     image_barrier[0].image = src_image;
12895     image_barrier[0].subresourceRange.layerCount = 2;
12896     image_barrier[0].subresourceRange.levelCount = 2;
12897     image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12898     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from "
12899                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when "
12900                                                                         "current layout is VK_IMAGE_LAYOUT_GENERAL.");
12901     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
12902                          NULL, 0, NULL, 1, image_barrier);
12903     m_errorMonitor->VerifyFound();
12904
12905     // Finally some layout errors at RenderPass create time
12906     // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
12907     VkAttachmentReference attach = {};
12908     // perf warning for GENERAL layout w/ non-DS input attachment
12909     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12910     VkSubpassDescription subpass = {};
12911     subpass.inputAttachmentCount = 1;
12912     subpass.pInputAttachments = &attach;
12913     VkRenderPassCreateInfo rpci = {};
12914     rpci.subpassCount = 1;
12915     rpci.pSubpasses = &subpass;
12916     rpci.attachmentCount = 1;
12917     VkAttachmentDescription attach_desc = {};
12918     attach_desc.format = VK_FORMAT_UNDEFINED;
12919     rpci.pAttachments = &attach_desc;
12920     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12921     VkRenderPass rp;
12922     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12923                                          "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
12924     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12925     m_errorMonitor->VerifyFound();
12926     // error w/ non-general layout
12927     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12928
12929     m_errorMonitor->SetDesiredFailureMsg(
12930         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12931         "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
12932     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12933     m_errorMonitor->VerifyFound();
12934     subpass.inputAttachmentCount = 0;
12935     subpass.colorAttachmentCount = 1;
12936     subpass.pColorAttachments = &attach;
12937     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12938     // perf warning for GENERAL layout on color attachment
12939     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12940                                          "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
12941     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12942     m_errorMonitor->VerifyFound();
12943     // error w/ non-color opt or GENERAL layout for color attachment
12944     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12945     m_errorMonitor->SetDesiredFailureMsg(
12946         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12947         "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
12948     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12949     m_errorMonitor->VerifyFound();
12950     subpass.colorAttachmentCount = 0;
12951     subpass.pDepthStencilAttachment = &attach;
12952     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12953     // perf warning for GENERAL layout on DS attachment
12954     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12955                                          "GENERAL layout for depth attachment may not give optimal performance.");
12956     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12957     m_errorMonitor->VerifyFound();
12958     // error w/ non-ds opt or GENERAL layout for color attachment
12959     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12960     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12961                                          "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
12962                                          "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
12963     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12964     m_errorMonitor->VerifyFound();
12965     // For this error we need a valid renderpass so create default one
12966     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12967     attach.attachment = 0;
12968     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
12969     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12970     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
12971     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
12972     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
12973     // Can't do a CLEAR load on READ_ONLY initialLayout
12974     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
12975     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12976     attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12977     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout "
12978                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_"
12979                                                                         "ONLY_OPTIMAL");
12980     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12981     m_errorMonitor->VerifyFound();
12982
12983     vkDestroyImage(m_device->device(), src_image, NULL);
12984     vkDestroyImage(m_device->device(), dst_image, NULL);
12985 }
12986
12987 TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
12988     TEST_DESCRIPTION("Positive test where we create a renderpass with an "
12989                      "attachment that uses LOAD_OP_CLEAR, the first subpass "
12990                      "has a valid layout, and a second subpass then uses a "
12991                      "valid *READ_ONLY* layout.");
12992     m_errorMonitor->ExpectSuccess();
12993     ASSERT_NO_FATAL_FAILURE(InitState());
12994
12995     VkAttachmentReference attach[2] = {};
12996     attach[0].attachment = 0;
12997     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
12998     attach[1].attachment = 0;
12999     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13000     VkSubpassDescription subpasses[2] = {};
13001     // First subpass clears DS attach on load
13002     subpasses[0].pDepthStencilAttachment = &attach[0];
13003     // 2nd subpass reads in DS as input attachment
13004     subpasses[1].inputAttachmentCount = 1;
13005     subpasses[1].pInputAttachments = &attach[1];
13006     VkAttachmentDescription attach_desc = {};
13007     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
13008     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
13009     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
13010     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
13011     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13012     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13013     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13014     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13015     VkRenderPassCreateInfo rpci = {};
13016     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
13017     rpci.attachmentCount = 1;
13018     rpci.pAttachments = &attach_desc;
13019     rpci.subpassCount = 2;
13020     rpci.pSubpasses = subpasses;
13021
13022     // Now create RenderPass and verify no errors
13023     VkRenderPass rp;
13024     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
13025     m_errorMonitor->VerifyNotFound();
13026
13027     vkDestroyRenderPass(m_device->device(), rp, NULL);
13028 }
13029
13030 TEST_F(VkLayerTest, SimultaneousUse) {
13031     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13032                      "in primary and secondary command buffers.");
13033
13034     ASSERT_NO_FATAL_FAILURE(InitState());
13035     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13036
13037     const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
13038     const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
13039                                             "will cause primary command buffer";
13040
13041     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
13042     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13043     command_buffer_allocate_info.commandPool = m_commandPool;
13044     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13045     command_buffer_allocate_info.commandBufferCount = 1;
13046
13047     VkCommandBuffer secondary_command_buffer;
13048     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
13049     VkCommandBufferBeginInfo command_buffer_begin_info = {};
13050     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
13051     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
13052     command_buffer_inheritance_info.renderPass = m_renderPass;
13053     command_buffer_inheritance_info.framebuffer = m_framebuffer;
13054     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13055     command_buffer_begin_info.flags =
13056         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13057     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
13058
13059     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
13060     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13061     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13062     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13063     vkEndCommandBuffer(secondary_command_buffer);
13064
13065     VkSubmitInfo submit_info = {};
13066     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13067     submit_info.commandBufferCount = 1;
13068     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13069     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13070
13071     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13072     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13073     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1);
13074     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13075     m_errorMonitor->VerifyFound();
13076     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13077     vkEndCommandBuffer(m_commandBuffer->handle());
13078
13079     m_errorMonitor->SetDesiredFailureMsg(0, "");
13080     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13081
13082     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
13083     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13084     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13085
13086     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2);
13087     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13088     m_errorMonitor->VerifyFound();
13089     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13090     vkEndCommandBuffer(m_commandBuffer->handle());
13091 }
13092
13093 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
13094     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13095                      "in primary and secondary command buffers. "
13096                      "Delete objects that are inuse. Call VkQueueSubmit "
13097                      "with an event that has been deleted.");
13098
13099     ASSERT_NO_FATAL_FAILURE(InitState());
13100     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13101
13102     const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x";
13103     const char *cannot_delete_event_message = "Cannot delete event 0x";
13104     const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x";
13105     const char *cannot_destroy_fence_message = "Fence 0x";
13106
13107     BeginCommandBuffer();
13108
13109     VkEvent event;
13110     VkEventCreateInfo event_create_info = {};
13111     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
13112     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13113     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13114
13115     EndCommandBuffer();
13116     vkDestroyEvent(m_device->device(), event, nullptr);
13117
13118     VkSubmitInfo submit_info = {};
13119     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13120     submit_info.commandBufferCount = 1;
13121     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message);
13123     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13124     m_errorMonitor->VerifyFound();
13125
13126     m_errorMonitor->SetDesiredFailureMsg(0, "");
13127     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13128
13129     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13130
13131     VkSemaphoreCreateInfo semaphore_create_info = {};
13132     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13133     VkSemaphore semaphore;
13134     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13135     VkFenceCreateInfo fence_create_info = {};
13136     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13137     VkFence fence;
13138     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13139
13140     VkDescriptorPoolSize descriptor_pool_type_count = {};
13141     descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13142     descriptor_pool_type_count.descriptorCount = 1;
13143
13144     VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
13145     descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13146     descriptor_pool_create_info.maxSets = 1;
13147     descriptor_pool_create_info.poolSizeCount = 1;
13148     descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
13149     descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
13150
13151     VkDescriptorPool descriptorset_pool;
13152     ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
13153
13154     VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
13155     descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13156     descriptorset_layout_binding.descriptorCount = 1;
13157     descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
13158
13159     VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
13160     descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13161     descriptorset_layout_create_info.bindingCount = 1;
13162     descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
13163
13164     VkDescriptorSetLayout descriptorset_layout;
13165     ASSERT_VK_SUCCESS(
13166         vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
13167
13168     VkDescriptorSet descriptorset;
13169     VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
13170     descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13171     descriptorset_allocate_info.descriptorSetCount = 1;
13172     descriptorset_allocate_info.descriptorPool = descriptorset_pool;
13173     descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
13174     ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
13175
13176     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
13177
13178     VkDescriptorBufferInfo buffer_info = {};
13179     buffer_info.buffer = buffer_test.GetBuffer();
13180     buffer_info.offset = 0;
13181     buffer_info.range = 1024;
13182
13183     VkWriteDescriptorSet write_descriptor_set = {};
13184     write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13185     write_descriptor_set.dstSet = descriptorset;
13186     write_descriptor_set.descriptorCount = 1;
13187     write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13188     write_descriptor_set.pBufferInfo = &buffer_info;
13189
13190     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
13191
13192     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13193     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13194
13195     VkPipelineObj pipe(m_device);
13196     pipe.AddColorAttachment();
13197     pipe.AddShader(&vs);
13198     pipe.AddShader(&fs);
13199
13200     VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
13201     pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13202     pipeline_layout_create_info.setLayoutCount = 1;
13203     pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
13204
13205     VkPipelineLayout pipeline_layout;
13206     ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
13207
13208     pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
13209
13210     BeginCommandBuffer();
13211     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13212
13213     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13214     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13215                             &descriptorset, 0, NULL);
13216
13217     EndCommandBuffer();
13218
13219     submit_info.signalSemaphoreCount = 1;
13220     submit_info.pSignalSemaphores = &semaphore;
13221     vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
13222
13223     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message);
13224     vkDestroyEvent(m_device->device(), event, nullptr);
13225     m_errorMonitor->VerifyFound();
13226
13227     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message);
13228     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13229     m_errorMonitor->VerifyFound();
13230
13231     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message);
13232     vkDestroyFence(m_device->device(), fence, nullptr);
13233     m_errorMonitor->VerifyFound();
13234
13235     vkQueueWaitIdle(m_device->m_queue);
13236     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13237     vkDestroyFence(m_device->device(), fence, nullptr);
13238     vkDestroyEvent(m_device->device(), event, nullptr);
13239     vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
13240     vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
13241     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
13242 }
13243
13244 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
13245     TEST_DESCRIPTION("Delete in-use query pool.");
13246
13247     ASSERT_NO_FATAL_FAILURE(InitState());
13248     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13249
13250     VkQueryPool query_pool;
13251     VkQueryPoolCreateInfo query_pool_ci{};
13252     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
13253     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
13254     query_pool_ci.queryCount = 1;
13255     vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13256     BeginCommandBuffer();
13257     // Reset query pool to create binding with cmd buffer
13258     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13259
13260     EndCommandBuffer();
13261
13262     VkSubmitInfo submit_info = {};
13263     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13264     submit_info.commandBufferCount = 1;
13265     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13266     // Submit cmd buffer and then destroy query pool while in-flight
13267     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13268
13269     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x");
13270     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13271     m_errorMonitor->VerifyFound();
13272
13273     vkQueueWaitIdle(m_device->m_queue);
13274     // Now that cmd buffer done we can safely destroy query_pool
13275     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13276 }
13277
13278 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
13279     TEST_DESCRIPTION("Delete in-use pipeline.");
13280
13281     ASSERT_NO_FATAL_FAILURE(InitState());
13282     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13283
13284     // Empty pipeline layout used for binding PSO
13285     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13286     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13287     pipeline_layout_ci.setLayoutCount = 0;
13288     pipeline_layout_ci.pSetLayouts = NULL;
13289
13290     VkPipelineLayout pipeline_layout;
13291     VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout);
13292     ASSERT_VK_SUCCESS(err);
13293
13294     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x");
13295     // Create PSO to be used for draw-time errors below
13296     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13297     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13298     // Store pipeline handle so we can actually delete it before test finishes
13299     VkPipeline delete_this_pipeline;
13300     { // Scope pipeline so it will be auto-deleted
13301         VkPipelineObj pipe(m_device);
13302         pipe.AddShader(&vs);
13303         pipe.AddShader(&fs);
13304         pipe.AddColorAttachment();
13305         pipe.CreateVKPipeline(pipeline_layout, renderPass());
13306         delete_this_pipeline = pipe.handle();
13307
13308         BeginCommandBuffer();
13309         // Bind pipeline to cmd buffer
13310         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13311
13312         EndCommandBuffer();
13313
13314         VkSubmitInfo submit_info = {};
13315         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13316         submit_info.commandBufferCount = 1;
13317         submit_info.pCommandBuffers = &m_commandBuffer->handle();
13318         // Submit cmd buffer and then pipeline destroyed while in-flight
13319         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13320     } // Pipeline deletion triggered here
13321     m_errorMonitor->VerifyFound();
13322     // Make sure queue finished and then actually delete pipeline
13323     vkQueueWaitIdle(m_device->m_queue);
13324     vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
13325     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
13326 }
13327
13328 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
13329     TEST_DESCRIPTION("Delete in-use imageView.");
13330
13331     ASSERT_NO_FATAL_FAILURE(InitState());
13332     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13333
13334     VkDescriptorPoolSize ds_type_count;
13335     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13336     ds_type_count.descriptorCount = 1;
13337
13338     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13339     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13340     ds_pool_ci.maxSets = 1;
13341     ds_pool_ci.poolSizeCount = 1;
13342     ds_pool_ci.pPoolSizes = &ds_type_count;
13343
13344     VkDescriptorPool ds_pool;
13345     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13346     ASSERT_VK_SUCCESS(err);
13347
13348     VkSamplerCreateInfo sampler_ci = {};
13349     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13350     sampler_ci.pNext = NULL;
13351     sampler_ci.magFilter = VK_FILTER_NEAREST;
13352     sampler_ci.minFilter = VK_FILTER_NEAREST;
13353     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13354     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13355     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13356     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13357     sampler_ci.mipLodBias = 1.0;
13358     sampler_ci.anisotropyEnable = VK_FALSE;
13359     sampler_ci.maxAnisotropy = 1;
13360     sampler_ci.compareEnable = VK_FALSE;
13361     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13362     sampler_ci.minLod = 1.0;
13363     sampler_ci.maxLod = 1.0;
13364     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13365     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13366     VkSampler sampler;
13367
13368     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13369     ASSERT_VK_SUCCESS(err);
13370
13371     VkDescriptorSetLayoutBinding layout_binding;
13372     layout_binding.binding = 0;
13373     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13374     layout_binding.descriptorCount = 1;
13375     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13376     layout_binding.pImmutableSamplers = NULL;
13377
13378     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13379     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13380     ds_layout_ci.bindingCount = 1;
13381     ds_layout_ci.pBindings = &layout_binding;
13382     VkDescriptorSetLayout ds_layout;
13383     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13384     ASSERT_VK_SUCCESS(err);
13385
13386     VkDescriptorSetAllocateInfo alloc_info = {};
13387     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13388     alloc_info.descriptorSetCount = 1;
13389     alloc_info.descriptorPool = ds_pool;
13390     alloc_info.pSetLayouts = &ds_layout;
13391     VkDescriptorSet descriptor_set;
13392     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13393     ASSERT_VK_SUCCESS(err);
13394
13395     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13396     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13397     pipeline_layout_ci.pNext = NULL;
13398     pipeline_layout_ci.setLayoutCount = 1;
13399     pipeline_layout_ci.pSetLayouts = &ds_layout;
13400
13401     VkPipelineLayout pipeline_layout;
13402     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13403     ASSERT_VK_SUCCESS(err);
13404
13405     VkImageObj image(m_device);
13406     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13407     ASSERT_TRUE(image.initialized());
13408
13409     VkImageView view;
13410     VkImageViewCreateInfo ivci = {};
13411     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13412     ivci.image = image.handle();
13413     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13414     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13415     ivci.subresourceRange.layerCount = 1;
13416     ivci.subresourceRange.baseMipLevel = 0;
13417     ivci.subresourceRange.levelCount = 1;
13418     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13419
13420     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13421     ASSERT_VK_SUCCESS(err);
13422
13423     VkDescriptorImageInfo image_info{};
13424     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13425     image_info.imageView = view;
13426     image_info.sampler = sampler;
13427
13428     VkWriteDescriptorSet descriptor_write = {};
13429     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13430     descriptor_write.dstSet = descriptor_set;
13431     descriptor_write.dstBinding = 0;
13432     descriptor_write.descriptorCount = 1;
13433     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13434     descriptor_write.pImageInfo = &image_info;
13435
13436     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13437
13438     // Create PSO to use the sampler
13439     char const *vsSource = "#version 450\n"
13440                            "\n"
13441                            "out gl_PerVertex { \n"
13442                            "    vec4 gl_Position;\n"
13443                            "};\n"
13444                            "void main(){\n"
13445                            "   gl_Position = vec4(1);\n"
13446                            "}\n";
13447     char const *fsSource = "#version 450\n"
13448                            "\n"
13449                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13450                            "layout(location=0) out vec4 x;\n"
13451                            "void main(){\n"
13452                            "   x = texture(s, vec2(1));\n"
13453                            "}\n";
13454     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13455     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13456     VkPipelineObj pipe(m_device);
13457     pipe.AddShader(&vs);
13458     pipe.AddShader(&fs);
13459     pipe.AddColorAttachment();
13460     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13461
13462     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
13463
13464     BeginCommandBuffer();
13465     // Bind pipeline to cmd buffer
13466     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13467     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13468                             &descriptor_set, 0, nullptr);
13469     Draw(1, 0, 0, 0);
13470     EndCommandBuffer();
13471     // Submit cmd buffer then destroy sampler
13472     VkSubmitInfo submit_info = {};
13473     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13474     submit_info.commandBufferCount = 1;
13475     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13476     // Submit cmd buffer and then destroy imageView while in-flight
13477     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13478
13479     vkDestroyImageView(m_device->device(), view, nullptr);
13480     m_errorMonitor->VerifyFound();
13481     vkQueueWaitIdle(m_device->m_queue);
13482     // Now we can actually destroy imageView
13483     vkDestroyImageView(m_device->device(), view, NULL);
13484     vkDestroySampler(m_device->device(), sampler, nullptr);
13485     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13486     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13487     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13488 }
13489
13490 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
13491     TEST_DESCRIPTION("Delete in-use bufferView.");
13492
13493     ASSERT_NO_FATAL_FAILURE(InitState());
13494     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13495
13496     VkDescriptorPoolSize ds_type_count;
13497     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13498     ds_type_count.descriptorCount = 1;
13499
13500     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13501     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13502     ds_pool_ci.maxSets = 1;
13503     ds_pool_ci.poolSizeCount = 1;
13504     ds_pool_ci.pPoolSizes = &ds_type_count;
13505
13506     VkDescriptorPool ds_pool;
13507     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13508     ASSERT_VK_SUCCESS(err);
13509
13510     VkDescriptorSetLayoutBinding layout_binding;
13511     layout_binding.binding = 0;
13512     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13513     layout_binding.descriptorCount = 1;
13514     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13515     layout_binding.pImmutableSamplers = NULL;
13516
13517     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13518     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13519     ds_layout_ci.bindingCount = 1;
13520     ds_layout_ci.pBindings = &layout_binding;
13521     VkDescriptorSetLayout ds_layout;
13522     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13523     ASSERT_VK_SUCCESS(err);
13524
13525     VkDescriptorSetAllocateInfo alloc_info = {};
13526     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13527     alloc_info.descriptorSetCount = 1;
13528     alloc_info.descriptorPool = ds_pool;
13529     alloc_info.pSetLayouts = &ds_layout;
13530     VkDescriptorSet descriptor_set;
13531     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13532     ASSERT_VK_SUCCESS(err);
13533
13534     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13535     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13536     pipeline_layout_ci.pNext = NULL;
13537     pipeline_layout_ci.setLayoutCount = 1;
13538     pipeline_layout_ci.pSetLayouts = &ds_layout;
13539
13540     VkPipelineLayout pipeline_layout;
13541     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13542     ASSERT_VK_SUCCESS(err);
13543
13544     VkBuffer buffer;
13545     uint32_t queue_family_index = 0;
13546     VkBufferCreateInfo buffer_create_info = {};
13547     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
13548     buffer_create_info.size = 1024;
13549     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
13550     buffer_create_info.queueFamilyIndexCount = 1;
13551     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
13552
13553     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
13554     ASSERT_VK_SUCCESS(err);
13555
13556     VkMemoryRequirements memory_reqs;
13557     VkDeviceMemory buffer_memory;
13558
13559     VkMemoryAllocateInfo memory_info = {};
13560     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
13561     memory_info.allocationSize = 0;
13562     memory_info.memoryTypeIndex = 0;
13563
13564     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
13565     memory_info.allocationSize = memory_reqs.size;
13566     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
13567     ASSERT_TRUE(pass);
13568
13569     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
13570     ASSERT_VK_SUCCESS(err);
13571     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
13572     ASSERT_VK_SUCCESS(err);
13573
13574     VkBufferView view;
13575     VkBufferViewCreateInfo bvci = {};
13576     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
13577     bvci.buffer = buffer;
13578     bvci.format = VK_FORMAT_R8_UNORM;
13579     bvci.range = VK_WHOLE_SIZE;
13580
13581     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
13582     ASSERT_VK_SUCCESS(err);
13583
13584     VkWriteDescriptorSet descriptor_write = {};
13585     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13586     descriptor_write.dstSet = descriptor_set;
13587     descriptor_write.dstBinding = 0;
13588     descriptor_write.descriptorCount = 1;
13589     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13590     descriptor_write.pTexelBufferView = &view;
13591
13592     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13593
13594     char const *vsSource = "#version 450\n"
13595                            "\n"
13596                            "out gl_PerVertex { \n"
13597                            "    vec4 gl_Position;\n"
13598                            "};\n"
13599                            "void main(){\n"
13600                            "   gl_Position = vec4(1);\n"
13601                            "}\n";
13602     char const *fsSource = "#version 450\n"
13603                            "\n"
13604                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
13605                            "layout(location=0) out vec4 x;\n"
13606                            "void main(){\n"
13607                            "   x = imageLoad(s, 0);\n"
13608                            "}\n";
13609     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13610     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13611     VkPipelineObj pipe(m_device);
13612     pipe.AddShader(&vs);
13613     pipe.AddShader(&fs);
13614     pipe.AddColorAttachment();
13615     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13616
13617     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
13618
13619     BeginCommandBuffer();
13620     VkViewport viewport = {0, 0, 16, 16, 0, 1};
13621     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
13622     VkRect2D scissor = {{0, 0}, {16, 16}};
13623     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
13624     // Bind pipeline to cmd buffer
13625     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13626     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13627                             &descriptor_set, 0, nullptr);
13628     Draw(1, 0, 0, 0);
13629     EndCommandBuffer();
13630
13631     VkSubmitInfo submit_info = {};
13632     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13633     submit_info.commandBufferCount = 1;
13634     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13635     // Submit cmd buffer and then destroy bufferView while in-flight
13636     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13637
13638     vkDestroyBufferView(m_device->device(), view, nullptr);
13639     m_errorMonitor->VerifyFound();
13640     vkQueueWaitIdle(m_device->m_queue);
13641     // Now we can actually destroy bufferView
13642     vkDestroyBufferView(m_device->device(), view, NULL);
13643     vkDestroyBuffer(m_device->device(), buffer, NULL);
13644     vkFreeMemory(m_device->device(), buffer_memory, NULL);
13645     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13646     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13647     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13648 }
13649
13650 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
13651     TEST_DESCRIPTION("Delete in-use sampler.");
13652
13653     ASSERT_NO_FATAL_FAILURE(InitState());
13654     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13655
13656     VkDescriptorPoolSize ds_type_count;
13657     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13658     ds_type_count.descriptorCount = 1;
13659
13660     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13661     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13662     ds_pool_ci.maxSets = 1;
13663     ds_pool_ci.poolSizeCount = 1;
13664     ds_pool_ci.pPoolSizes = &ds_type_count;
13665
13666     VkDescriptorPool ds_pool;
13667     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13668     ASSERT_VK_SUCCESS(err);
13669
13670     VkSamplerCreateInfo sampler_ci = {};
13671     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13672     sampler_ci.pNext = NULL;
13673     sampler_ci.magFilter = VK_FILTER_NEAREST;
13674     sampler_ci.minFilter = VK_FILTER_NEAREST;
13675     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13676     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13677     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13678     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13679     sampler_ci.mipLodBias = 1.0;
13680     sampler_ci.anisotropyEnable = VK_FALSE;
13681     sampler_ci.maxAnisotropy = 1;
13682     sampler_ci.compareEnable = VK_FALSE;
13683     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13684     sampler_ci.minLod = 1.0;
13685     sampler_ci.maxLod = 1.0;
13686     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13687     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13688     VkSampler sampler;
13689
13690     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13691     ASSERT_VK_SUCCESS(err);
13692
13693     VkDescriptorSetLayoutBinding layout_binding;
13694     layout_binding.binding = 0;
13695     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13696     layout_binding.descriptorCount = 1;
13697     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13698     layout_binding.pImmutableSamplers = NULL;
13699
13700     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13701     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13702     ds_layout_ci.bindingCount = 1;
13703     ds_layout_ci.pBindings = &layout_binding;
13704     VkDescriptorSetLayout ds_layout;
13705     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13706     ASSERT_VK_SUCCESS(err);
13707
13708     VkDescriptorSetAllocateInfo alloc_info = {};
13709     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13710     alloc_info.descriptorSetCount = 1;
13711     alloc_info.descriptorPool = ds_pool;
13712     alloc_info.pSetLayouts = &ds_layout;
13713     VkDescriptorSet descriptor_set;
13714     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13715     ASSERT_VK_SUCCESS(err);
13716
13717     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13718     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13719     pipeline_layout_ci.pNext = NULL;
13720     pipeline_layout_ci.setLayoutCount = 1;
13721     pipeline_layout_ci.pSetLayouts = &ds_layout;
13722
13723     VkPipelineLayout pipeline_layout;
13724     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13725     ASSERT_VK_SUCCESS(err);
13726
13727     VkImageObj image(m_device);
13728     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13729     ASSERT_TRUE(image.initialized());
13730
13731     VkImageView view;
13732     VkImageViewCreateInfo ivci = {};
13733     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13734     ivci.image = image.handle();
13735     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13736     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13737     ivci.subresourceRange.layerCount = 1;
13738     ivci.subresourceRange.baseMipLevel = 0;
13739     ivci.subresourceRange.levelCount = 1;
13740     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13741
13742     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13743     ASSERT_VK_SUCCESS(err);
13744
13745     VkDescriptorImageInfo image_info{};
13746     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13747     image_info.imageView = view;
13748     image_info.sampler = sampler;
13749
13750     VkWriteDescriptorSet descriptor_write = {};
13751     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13752     descriptor_write.dstSet = descriptor_set;
13753     descriptor_write.dstBinding = 0;
13754     descriptor_write.descriptorCount = 1;
13755     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13756     descriptor_write.pImageInfo = &image_info;
13757
13758     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13759
13760     // Create PSO to use the sampler
13761     char const *vsSource = "#version 450\n"
13762                            "\n"
13763                            "out gl_PerVertex { \n"
13764                            "    vec4 gl_Position;\n"
13765                            "};\n"
13766                            "void main(){\n"
13767                            "   gl_Position = vec4(1);\n"
13768                            "}\n";
13769     char const *fsSource = "#version 450\n"
13770                            "\n"
13771                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13772                            "layout(location=0) out vec4 x;\n"
13773                            "void main(){\n"
13774                            "   x = texture(s, vec2(1));\n"
13775                            "}\n";
13776     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13777     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13778     VkPipelineObj pipe(m_device);
13779     pipe.AddShader(&vs);
13780     pipe.AddShader(&fs);
13781     pipe.AddColorAttachment();
13782     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13783
13784     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x");
13785
13786     BeginCommandBuffer();
13787     // Bind pipeline to cmd buffer
13788     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13789     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13790                             &descriptor_set, 0, nullptr);
13791     Draw(1, 0, 0, 0);
13792     EndCommandBuffer();
13793     // Submit cmd buffer then destroy sampler
13794     VkSubmitInfo submit_info = {};
13795     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13796     submit_info.commandBufferCount = 1;
13797     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13798     // Submit cmd buffer and then destroy sampler while in-flight
13799     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13800
13801     vkDestroySampler(m_device->device(), sampler, nullptr);
13802     m_errorMonitor->VerifyFound();
13803     vkQueueWaitIdle(m_device->m_queue);
13804     // Now we can actually destroy sampler
13805     vkDestroySampler(m_device->device(), sampler, nullptr);
13806     vkDestroyImageView(m_device->device(), view, NULL);
13807     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13808     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13809     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13810 }
13811
13812 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
13813     TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already "
13814                      "signaled but not waited on by the queue. Wait on a "
13815                      "fence that has not yet been submitted to a queue.");
13816
13817     ASSERT_NO_FATAL_FAILURE(InitState());
13818     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13819
13820     const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
13821     const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during "
13822                                              "acquire next image.";
13823
13824     BeginCommandBuffer();
13825     EndCommandBuffer();
13826
13827     VkSemaphoreCreateInfo semaphore_create_info = {};
13828     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13829     VkSemaphore semaphore;
13830     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13831     VkSubmitInfo submit_info = {};
13832     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13833     submit_info.commandBufferCount = 1;
13834     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13835     submit_info.signalSemaphoreCount = 1;
13836     submit_info.pSignalSemaphores = &semaphore;
13837     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13838     m_errorMonitor->SetDesiredFailureMsg(0, "");
13839     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13840     BeginCommandBuffer();
13841     EndCommandBuffer();
13842     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
13843     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13844     m_errorMonitor->VerifyFound();
13845
13846     VkFenceCreateInfo fence_create_info = {};
13847     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13848     VkFence fence;
13849     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13850
13851     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
13852     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
13853     m_errorMonitor->VerifyFound();
13854
13855     vkDeviceWaitIdle(m_device->device());
13856     vkDestroyFence(m_device->device(), fence, nullptr);
13857     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13858 }
13859
13860 TEST_F(VkLayerTest, FramebufferIncompatible) {
13861     TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
13862                      "that does not match the framebuffer for the active "
13863                      "renderpass.");
13864     ASSERT_NO_FATAL_FAILURE(InitState());
13865     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13866
13867     // A renderpass with one color attachment.
13868     VkAttachmentDescription attachment = {0,
13869                                           VK_FORMAT_B8G8R8A8_UNORM,
13870                                           VK_SAMPLE_COUNT_1_BIT,
13871                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13872                                           VK_ATTACHMENT_STORE_OP_STORE,
13873                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13874                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
13875                                           VK_IMAGE_LAYOUT_UNDEFINED,
13876                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13877
13878     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13879
13880     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
13881
13882     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
13883
13884     VkRenderPass rp;
13885     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
13886     ASSERT_VK_SUCCESS(err);
13887
13888     // A compatible framebuffer.
13889     VkImageObj image(m_device);
13890     image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13891     ASSERT_TRUE(image.initialized());
13892
13893     VkImageViewCreateInfo ivci = {
13894         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
13895         nullptr,
13896         0,
13897         image.handle(),
13898         VK_IMAGE_VIEW_TYPE_2D,
13899         VK_FORMAT_B8G8R8A8_UNORM,
13900         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13901          VK_COMPONENT_SWIZZLE_IDENTITY},
13902         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
13903     };
13904     VkImageView view;
13905     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
13906     ASSERT_VK_SUCCESS(err);
13907
13908     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
13909     VkFramebuffer fb;
13910     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
13911     ASSERT_VK_SUCCESS(err);
13912
13913     VkCommandBufferAllocateInfo cbai = {};
13914     cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13915     cbai.commandPool = m_commandPool;
13916     cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13917     cbai.commandBufferCount = 1;
13918
13919     VkCommandBuffer sec_cb;
13920     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
13921     ASSERT_VK_SUCCESS(err);
13922     VkCommandBufferBeginInfo cbbi = {};
13923     VkCommandBufferInheritanceInfo cbii = {};
13924     cbii.renderPass = renderPass();
13925     cbii.framebuffer = fb;
13926     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13927     cbbi.pNext = NULL;
13928     cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13929     cbbi.pInheritanceInfo = &cbii;
13930     vkBeginCommandBuffer(sec_cb, &cbbi);
13931     vkEndCommandBuffer(sec_cb);
13932
13933     VkCommandBufferBeginInfo cbbi2 = {
13934         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
13935         0, nullptr
13936     };
13937     vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
13938     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13939
13940     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13941                                          " that is not the same as the primaryCB's current active framebuffer ");
13942     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
13943     m_errorMonitor->VerifyFound();
13944     // Cleanup
13945     vkDestroyImageView(m_device->device(), view, NULL);
13946     vkDestroyRenderPass(m_device->device(), rp, NULL);
13947     vkDestroyFramebuffer(m_device->device(), fb, NULL);
13948 }
13949
13950 TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
13951     TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
13952                      "invalid value. If logicOp is not available, attempt to "
13953                      "use it and verify that we see the correct error.");
13954     ASSERT_NO_FATAL_FAILURE(InitState());
13955     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13956
13957     auto features = m_device->phy().features();
13958     // Set the expected error depending on whether or not logicOp available
13959     if (VK_FALSE == features.logicOp) {
13960         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not "
13961                                                                             "enabled, logicOpEnable must be "
13962                                                                             "VK_FALSE");
13963     } else {
13964         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
13965     }
13966     // Create a pipeline using logicOp
13967     VkResult err;
13968
13969     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13970     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13971
13972     VkPipelineLayout pipeline_layout;
13973     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13974     ASSERT_VK_SUCCESS(err);
13975
13976     VkPipelineViewportStateCreateInfo vp_state_ci = {};
13977     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13978     vp_state_ci.viewportCount = 1;
13979     VkViewport vp = {}; // Just need dummy vp to point to
13980     vp_state_ci.pViewports = &vp;
13981     vp_state_ci.scissorCount = 1;
13982     VkRect2D scissors = {}; // Dummy scissors to point to
13983     vp_state_ci.pScissors = &scissors;
13984
13985     VkPipelineShaderStageCreateInfo shaderStages[2];
13986     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
13987
13988     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13989     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13990     shaderStages[0] = vs.GetStageCreateInfo();
13991     shaderStages[1] = fs.GetStageCreateInfo();
13992
13993     VkPipelineVertexInputStateCreateInfo vi_ci = {};
13994     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13995
13996     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
13997     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13998     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13999
14000     VkPipelineRasterizationStateCreateInfo rs_ci = {};
14001     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14002     rs_ci.lineWidth = 1.0f;
14003
14004     VkPipelineColorBlendAttachmentState att = {};
14005     att.blendEnable = VK_FALSE;
14006     att.colorWriteMask = 0xf;
14007
14008     VkPipelineColorBlendStateCreateInfo cb_ci = {};
14009     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
14010     // Enable logicOp & set logicOp to value 1 beyond allowed entries
14011     cb_ci.logicOpEnable = VK_TRUE;
14012     cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
14013     cb_ci.attachmentCount = 1;
14014     cb_ci.pAttachments = &att;
14015
14016     VkPipelineMultisampleStateCreateInfo ms_ci = {};
14017     ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14018     ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14019
14020     VkGraphicsPipelineCreateInfo gp_ci = {};
14021     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14022     gp_ci.stageCount = 2;
14023     gp_ci.pStages = shaderStages;
14024     gp_ci.pVertexInputState = &vi_ci;
14025     gp_ci.pInputAssemblyState = &ia_ci;
14026     gp_ci.pViewportState = &vp_state_ci;
14027     gp_ci.pRasterizationState = &rs_ci;
14028     gp_ci.pColorBlendState = &cb_ci;
14029     gp_ci.pMultisampleState = &ms_ci;
14030     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14031     gp_ci.layout = pipeline_layout;
14032     gp_ci.renderPass = renderPass();
14033
14034     VkPipelineCacheCreateInfo pc_ci = {};
14035     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14036
14037     VkPipeline pipeline;
14038     VkPipelineCache pipelineCache;
14039     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
14040     ASSERT_VK_SUCCESS(err);
14041
14042     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
14043     m_errorMonitor->VerifyFound();
14044     if (VK_SUCCESS == err) {
14045         vkDestroyPipeline(m_device->device(), pipeline, NULL);
14046     }
14047     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
14048     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
14049 }
14050 #endif // DRAW_STATE_TESTS
14051
14052 #if THREADING_TESTS
14053 #if GTEST_IS_THREADSAFE
14054 struct thread_data_struct {
14055     VkCommandBuffer commandBuffer;
14056     VkEvent event;
14057     bool bailout;
14058 };
14059
14060 extern "C" void *AddToCommandBuffer(void *arg) {
14061     struct thread_data_struct *data = (struct thread_data_struct *)arg;
14062
14063     for (int i = 0; i < 80000; i++) {
14064         vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
14065         if (data->bailout) {
14066             break;
14067         }
14068     }
14069     return NULL;
14070 }
14071
14072 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
14073     test_platform_thread thread;
14074
14075     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
14076
14077     ASSERT_NO_FATAL_FAILURE(InitState());
14078     ASSERT_NO_FATAL_FAILURE(InitViewport());
14079     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14080
14081     // Calls AllocateCommandBuffers
14082     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
14083
14084     // Avoid creating RenderPass
14085     commandBuffer.BeginCommandBuffer();
14086
14087     VkEventCreateInfo event_info;
14088     VkEvent event;
14089     VkResult err;
14090
14091     memset(&event_info, 0, sizeof(event_info));
14092     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
14093
14094     err = vkCreateEvent(device(), &event_info, NULL, &event);
14095     ASSERT_VK_SUCCESS(err);
14096
14097     err = vkResetEvent(device(), event);
14098     ASSERT_VK_SUCCESS(err);
14099
14100     struct thread_data_struct data;
14101     data.commandBuffer = commandBuffer.GetBufferHandle();
14102     data.event = event;
14103     data.bailout = false;
14104     m_errorMonitor->SetBailout(&data.bailout);
14105
14106     // First do some correct operations using multiple threads.
14107     // Add many entries to command buffer from another thread.
14108     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14109     // Make non-conflicting calls from this thread at the same time.
14110     for (int i = 0; i < 80000; i++) {
14111         uint32_t count;
14112         vkEnumeratePhysicalDevices(instance(), &count, NULL);
14113     }
14114     test_platform_thread_join(thread, NULL);
14115
14116     // Then do some incorrect operations using multiple threads.
14117     // Add many entries to command buffer from another thread.
14118     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14119     // Add many entries to command buffer from this thread at the same time.
14120     AddToCommandBuffer(&data);
14121
14122     test_platform_thread_join(thread, NULL);
14123     commandBuffer.EndCommandBuffer();
14124
14125     m_errorMonitor->SetBailout(NULL);
14126
14127     m_errorMonitor->VerifyFound();
14128
14129     vkDestroyEvent(device(), event, NULL);
14130 }
14131 #endif // GTEST_IS_THREADSAFE
14132 #endif // THREADING_TESTS
14133
14134 #if SHADER_CHECKER_TESTS
14135 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
14136     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14137                      "with an impossible code size");
14138
14139     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
14140
14141     ASSERT_NO_FATAL_FAILURE(InitState());
14142     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14143
14144     VkShaderModule module;
14145     VkShaderModuleCreateInfo moduleCreateInfo;
14146     struct icd_spv_header spv;
14147
14148     spv.magic = ICD_SPV_MAGIC;
14149     spv.version = ICD_SPV_VERSION;
14150     spv.gen_magic = 0;
14151
14152     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14153     moduleCreateInfo.pNext = NULL;
14154     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14155     moduleCreateInfo.codeSize = 4;
14156     moduleCreateInfo.flags = 0;
14157     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14158
14159     m_errorMonitor->VerifyFound();
14160 }
14161
14162 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
14163     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14164                      "with a bad magic number");
14165
14166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
14167
14168     ASSERT_NO_FATAL_FAILURE(InitState());
14169     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14170
14171     VkShaderModule module;
14172     VkShaderModuleCreateInfo moduleCreateInfo;
14173     struct icd_spv_header spv;
14174
14175     spv.magic = ~ICD_SPV_MAGIC;
14176     spv.version = ICD_SPV_VERSION;
14177     spv.gen_magic = 0;
14178
14179     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14180     moduleCreateInfo.pNext = NULL;
14181     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14182     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14183     moduleCreateInfo.flags = 0;
14184     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14185
14186     m_errorMonitor->VerifyFound();
14187 }
14188
14189 #if 0
14190 // Not currently covered by SPIRV-Tools validator
14191 TEST_F(VkLayerTest, InvalidSPIRVVersion) {
14192     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14193                                          "Invalid SPIR-V header");
14194
14195     ASSERT_NO_FATAL_FAILURE(InitState());
14196     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14197
14198     VkShaderModule module;
14199     VkShaderModuleCreateInfo moduleCreateInfo;
14200     struct icd_spv_header spv;
14201
14202     spv.magic = ICD_SPV_MAGIC;
14203     spv.version = ~ICD_SPV_VERSION;
14204     spv.gen_magic = 0;
14205
14206     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14207     moduleCreateInfo.pNext = NULL;
14208
14209     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14210     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14211     moduleCreateInfo.flags = 0;
14212     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14213
14214     m_errorMonitor->VerifyFound();
14215 }
14216 #endif
14217
14218 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
14219     TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
14220                      "is not consumed by the fragment stage");
14221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
14222
14223     ASSERT_NO_FATAL_FAILURE(InitState());
14224     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14225
14226     char const *vsSource = "#version 450\n"
14227                            "\n"
14228                            "layout(location=0) out float x;\n"
14229                            "out gl_PerVertex {\n"
14230                            "    vec4 gl_Position;\n"
14231                            "};\n"
14232                            "void main(){\n"
14233                            "   gl_Position = vec4(1);\n"
14234                            "   x = 0;\n"
14235                            "}\n";
14236     char const *fsSource = "#version 450\n"
14237                            "\n"
14238                            "layout(location=0) out vec4 color;\n"
14239                            "void main(){\n"
14240                            "   color = vec4(1);\n"
14241                            "}\n";
14242
14243     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14244     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14245
14246     VkPipelineObj pipe(m_device);
14247     pipe.AddColorAttachment();
14248     pipe.AddShader(&vs);
14249     pipe.AddShader(&fs);
14250
14251     VkDescriptorSetObj descriptorSet(m_device);
14252     descriptorSet.AppendDummy();
14253     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14254
14255     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14256
14257     m_errorMonitor->VerifyFound();
14258 }
14259
14260 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
14261     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14262                      "which is not present in the outputs of the previous stage");
14263
14264     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14265
14266     ASSERT_NO_FATAL_FAILURE(InitState());
14267     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14268
14269     char const *vsSource = "#version 450\n"
14270                            "\n"
14271                            "out gl_PerVertex {\n"
14272                            "    vec4 gl_Position;\n"
14273                            "};\n"
14274                            "void main(){\n"
14275                            "   gl_Position = vec4(1);\n"
14276                            "}\n";
14277     char const *fsSource = "#version 450\n"
14278                            "\n"
14279                            "layout(location=0) in float x;\n"
14280                            "layout(location=0) out vec4 color;\n"
14281                            "void main(){\n"
14282                            "   color = vec4(x);\n"
14283                            "}\n";
14284
14285     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14286     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14287
14288     VkPipelineObj pipe(m_device);
14289     pipe.AddColorAttachment();
14290     pipe.AddShader(&vs);
14291     pipe.AddShader(&fs);
14292
14293     VkDescriptorSetObj descriptorSet(m_device);
14294     descriptorSet.AppendDummy();
14295     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14296
14297     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14298
14299     m_errorMonitor->VerifyFound();
14300 }
14301
14302 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
14303     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14304                      "within an interace block, which is not present in the outputs "
14305                      "of the previous stage.");
14306     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14307
14308     ASSERT_NO_FATAL_FAILURE(InitState());
14309     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14310
14311     char const *vsSource = "#version 450\n"
14312                            "\n"
14313                            "out gl_PerVertex {\n"
14314                            "    vec4 gl_Position;\n"
14315                            "};\n"
14316                            "void main(){\n"
14317                            "   gl_Position = vec4(1);\n"
14318                            "}\n";
14319     char const *fsSource = "#version 450\n"
14320                            "\n"
14321                            "in block { layout(location=0) float x; } ins;\n"
14322                            "layout(location=0) out vec4 color;\n"
14323                            "void main(){\n"
14324                            "   color = vec4(ins.x);\n"
14325                            "}\n";
14326
14327     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14328     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14329
14330     VkPipelineObj pipe(m_device);
14331     pipe.AddColorAttachment();
14332     pipe.AddShader(&vs);
14333     pipe.AddShader(&fs);
14334
14335     VkDescriptorSetObj descriptorSet(m_device);
14336     descriptorSet.AppendDummy();
14337     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14338
14339     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14340
14341     m_errorMonitor->VerifyFound();
14342 }
14343
14344 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
14345     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
14346                      "across the VS->FS interface");
14347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
14348                                                                         "output arr[2] of float32' vs 'ptr to "
14349                                                                         "input arr[3] of float32'");
14350
14351     ASSERT_NO_FATAL_FAILURE(InitState());
14352     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14353
14354     char const *vsSource = "#version 450\n"
14355                            "\n"
14356                            "layout(location=0) out float x[2];\n"
14357                            "out gl_PerVertex {\n"
14358                            "    vec4 gl_Position;\n"
14359                            "};\n"
14360                            "void main(){\n"
14361                            "   x[0] = 0; x[1] = 0;\n"
14362                            "   gl_Position = vec4(1);\n"
14363                            "}\n";
14364     char const *fsSource = "#version 450\n"
14365                            "\n"
14366                            "layout(location=0) in float x[3];\n"
14367                            "layout(location=0) out vec4 color;\n"
14368                            "void main(){\n"
14369                            "   color = vec4(x[0] + x[1] + x[2]);\n"
14370                            "}\n";
14371
14372     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14373     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14374
14375     VkPipelineObj pipe(m_device);
14376     pipe.AddColorAttachment();
14377     pipe.AddShader(&vs);
14378     pipe.AddShader(&fs);
14379
14380     VkDescriptorSetObj descriptorSet(m_device);
14381     descriptorSet.AppendDummy();
14382     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14383
14384     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14385
14386     m_errorMonitor->VerifyFound();
14387 }
14388
14389 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
14390     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14391                      "the VS->FS interface");
14392     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14393
14394     ASSERT_NO_FATAL_FAILURE(InitState());
14395     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14396
14397     char const *vsSource = "#version 450\n"
14398                            "\n"
14399                            "layout(location=0) out int x;\n"
14400                            "out gl_PerVertex {\n"
14401                            "    vec4 gl_Position;\n"
14402                            "};\n"
14403                            "void main(){\n"
14404                            "   x = 0;\n"
14405                            "   gl_Position = vec4(1);\n"
14406                            "}\n";
14407     char const *fsSource = "#version 450\n"
14408                            "\n"
14409                            "layout(location=0) in float x;\n" /* VS writes int */
14410                            "layout(location=0) out vec4 color;\n"
14411                            "void main(){\n"
14412                            "   color = vec4(x);\n"
14413                            "}\n";
14414
14415     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14416     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14417
14418     VkPipelineObj pipe(m_device);
14419     pipe.AddColorAttachment();
14420     pipe.AddShader(&vs);
14421     pipe.AddShader(&fs);
14422
14423     VkDescriptorSetObj descriptorSet(m_device);
14424     descriptorSet.AppendDummy();
14425     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14426
14427     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14428
14429     m_errorMonitor->VerifyFound();
14430 }
14431
14432 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
14433     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14434                      "the VS->FS interface, when the variable is contained within "
14435                      "an interface block");
14436     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14437
14438     ASSERT_NO_FATAL_FAILURE(InitState());
14439     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14440
14441     char const *vsSource = "#version 450\n"
14442                            "\n"
14443                            "out block { layout(location=0) int x; } outs;\n"
14444                            "out gl_PerVertex {\n"
14445                            "    vec4 gl_Position;\n"
14446                            "};\n"
14447                            "void main(){\n"
14448                            "   outs.x = 0;\n"
14449                            "   gl_Position = vec4(1);\n"
14450                            "}\n";
14451     char const *fsSource = "#version 450\n"
14452                            "\n"
14453                            "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
14454                            "layout(location=0) out vec4 color;\n"
14455                            "void main(){\n"
14456                            "   color = vec4(ins.x);\n"
14457                            "}\n";
14458
14459     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14460     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14461
14462     VkPipelineObj pipe(m_device);
14463     pipe.AddColorAttachment();
14464     pipe.AddShader(&vs);
14465     pipe.AddShader(&fs);
14466
14467     VkDescriptorSetObj descriptorSet(m_device);
14468     descriptorSet.AppendDummy();
14469     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14470
14471     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14472
14473     m_errorMonitor->VerifyFound();
14474 }
14475
14476 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
14477     TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
14478                      "the VS->FS interface; This should manifest as a not-written/not-consumed "
14479                      "pair, but flushes out broken walking of the interfaces");
14480     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
14481
14482     ASSERT_NO_FATAL_FAILURE(InitState());
14483     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14484
14485     char const *vsSource = "#version 450\n"
14486                            "\n"
14487                            "out block { layout(location=1) float x; } outs;\n"
14488                            "out gl_PerVertex {\n"
14489                            "    vec4 gl_Position;\n"
14490                            "};\n"
14491                            "void main(){\n"
14492                            "   outs.x = 0;\n"
14493                            "   gl_Position = vec4(1);\n"
14494                            "}\n";
14495     char const *fsSource = "#version 450\n"
14496                            "\n"
14497                            "in block { layout(location=0) float x; } ins;\n"
14498                            "layout(location=0) out vec4 color;\n"
14499                            "void main(){\n"
14500                            "   color = vec4(ins.x);\n"
14501                            "}\n";
14502
14503     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14504     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14505
14506     VkPipelineObj pipe(m_device);
14507     pipe.AddColorAttachment();
14508     pipe.AddShader(&vs);
14509     pipe.AddShader(&fs);
14510
14511     VkDescriptorSetObj descriptorSet(m_device);
14512     descriptorSet.AppendDummy();
14513     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14514
14515     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14516
14517     m_errorMonitor->VerifyFound();
14518 }
14519
14520 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
14521     TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
14522                      "VS->FS interface. It's not enough to have the same set of locations in "
14523                      "use; matching is defined in terms of spirv variables.");
14524     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
14525
14526     ASSERT_NO_FATAL_FAILURE(InitState());
14527     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14528
14529     char const *vsSource = "#version 450\n"
14530                            "\n"
14531                            "out block { layout(location=0, component=0) float x; } outs;\n"
14532                            "out gl_PerVertex {\n"
14533                            "    vec4 gl_Position;\n"
14534                            "};\n"
14535                            "void main(){\n"
14536                            "   outs.x = 0;\n"
14537                            "   gl_Position = vec4(1);\n"
14538                            "}\n";
14539     char const *fsSource = "#version 450\n"
14540                            "\n"
14541                            "in block { layout(location=0, component=1) float x; } ins;\n"
14542                            "layout(location=0) out vec4 color;\n"
14543                            "void main(){\n"
14544                            "   color = vec4(ins.x);\n"
14545                            "}\n";
14546
14547     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14548     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14549
14550     VkPipelineObj pipe(m_device);
14551     pipe.AddColorAttachment();
14552     pipe.AddShader(&vs);
14553     pipe.AddShader(&fs);
14554
14555     VkDescriptorSetObj descriptorSet(m_device);
14556     descriptorSet.AppendDummy();
14557     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14558
14559     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14560
14561     m_errorMonitor->VerifyFound();
14562 }
14563
14564 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
14565     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
14566                      "not consumed by the vertex shader");
14567     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14568
14569     ASSERT_NO_FATAL_FAILURE(InitState());
14570     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14571
14572     VkVertexInputBindingDescription input_binding;
14573     memset(&input_binding, 0, sizeof(input_binding));
14574
14575     VkVertexInputAttributeDescription input_attrib;
14576     memset(&input_attrib, 0, sizeof(input_attrib));
14577     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14578
14579     char const *vsSource = "#version 450\n"
14580                            "\n"
14581                            "out gl_PerVertex {\n"
14582                            "    vec4 gl_Position;\n"
14583                            "};\n"
14584                            "void main(){\n"
14585                            "   gl_Position = vec4(1);\n"
14586                            "}\n";
14587     char const *fsSource = "#version 450\n"
14588                            "\n"
14589                            "layout(location=0) out vec4 color;\n"
14590                            "void main(){\n"
14591                            "   color = vec4(1);\n"
14592                            "}\n";
14593
14594     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14595     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14596
14597     VkPipelineObj pipe(m_device);
14598     pipe.AddColorAttachment();
14599     pipe.AddShader(&vs);
14600     pipe.AddShader(&fs);
14601
14602     pipe.AddVertexInputBindings(&input_binding, 1);
14603     pipe.AddVertexInputAttribs(&input_attrib, 1);
14604
14605     VkDescriptorSetObj descriptorSet(m_device);
14606     descriptorSet.AppendDummy();
14607     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14608
14609     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14610
14611     m_errorMonitor->VerifyFound();
14612 }
14613
14614 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
14615     TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
14616                      "vertex attributes. This flushes out bad behavior in the interface walker");
14617     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14618
14619     ASSERT_NO_FATAL_FAILURE(InitState());
14620     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14621
14622     VkVertexInputBindingDescription input_binding;
14623     memset(&input_binding, 0, sizeof(input_binding));
14624
14625     VkVertexInputAttributeDescription input_attrib;
14626     memset(&input_attrib, 0, sizeof(input_attrib));
14627     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14628
14629     char const *vsSource = "#version 450\n"
14630                            "\n"
14631                            "layout(location=1) in float x;\n"
14632                            "out gl_PerVertex {\n"
14633                            "    vec4 gl_Position;\n"
14634                            "};\n"
14635                            "void main(){\n"
14636                            "   gl_Position = vec4(x);\n"
14637                            "}\n";
14638     char const *fsSource = "#version 450\n"
14639                            "\n"
14640                            "layout(location=0) out vec4 color;\n"
14641                            "void main(){\n"
14642                            "   color = vec4(1);\n"
14643                            "}\n";
14644
14645     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14646     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14647
14648     VkPipelineObj pipe(m_device);
14649     pipe.AddColorAttachment();
14650     pipe.AddShader(&vs);
14651     pipe.AddShader(&fs);
14652
14653     pipe.AddVertexInputBindings(&input_binding, 1);
14654     pipe.AddVertexInputAttribs(&input_attrib, 1);
14655
14656     VkDescriptorSetObj descriptorSet(m_device);
14657     descriptorSet.AppendDummy();
14658     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14659
14660     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14661
14662     m_errorMonitor->VerifyFound();
14663 }
14664
14665 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
14666     TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
14667                      "provided by a vertex attribute");
14668     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
14669
14670     ASSERT_NO_FATAL_FAILURE(InitState());
14671     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14672
14673     char const *vsSource = "#version 450\n"
14674                            "\n"
14675                            "layout(location=0) in vec4 x;\n" /* not provided */
14676                            "out gl_PerVertex {\n"
14677                            "    vec4 gl_Position;\n"
14678                            "};\n"
14679                            "void main(){\n"
14680                            "   gl_Position = x;\n"
14681                            "}\n";
14682     char const *fsSource = "#version 450\n"
14683                            "\n"
14684                            "layout(location=0) out vec4 color;\n"
14685                            "void main(){\n"
14686                            "   color = vec4(1);\n"
14687                            "}\n";
14688
14689     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14690     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14691
14692     VkPipelineObj pipe(m_device);
14693     pipe.AddColorAttachment();
14694     pipe.AddShader(&vs);
14695     pipe.AddShader(&fs);
14696
14697     VkDescriptorSetObj descriptorSet(m_device);
14698     descriptorSet.AppendDummy();
14699     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14700
14701     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14702
14703     m_errorMonitor->VerifyFound();
14704 }
14705
14706 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
14707     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
14708                      "fundamental type (float/int/uint) of an attribute and the "
14709                      "vertex shader input that consumes it");
14710     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
14711
14712     ASSERT_NO_FATAL_FAILURE(InitState());
14713     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14714
14715     VkVertexInputBindingDescription input_binding;
14716     memset(&input_binding, 0, sizeof(input_binding));
14717
14718     VkVertexInputAttributeDescription input_attrib;
14719     memset(&input_attrib, 0, sizeof(input_attrib));
14720     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14721
14722     char const *vsSource = "#version 450\n"
14723                            "\n"
14724                            "layout(location=0) in int x;\n" /* attrib provided float */
14725                            "out gl_PerVertex {\n"
14726                            "    vec4 gl_Position;\n"
14727                            "};\n"
14728                            "void main(){\n"
14729                            "   gl_Position = vec4(x);\n"
14730                            "}\n";
14731     char const *fsSource = "#version 450\n"
14732                            "\n"
14733                            "layout(location=0) out vec4 color;\n"
14734                            "void main(){\n"
14735                            "   color = vec4(1);\n"
14736                            "}\n";
14737
14738     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14739     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14740
14741     VkPipelineObj pipe(m_device);
14742     pipe.AddColorAttachment();
14743     pipe.AddShader(&vs);
14744     pipe.AddShader(&fs);
14745
14746     pipe.AddVertexInputBindings(&input_binding, 1);
14747     pipe.AddVertexInputAttribs(&input_attrib, 1);
14748
14749     VkDescriptorSetObj descriptorSet(m_device);
14750     descriptorSet.AppendDummy();
14751     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14752
14753     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14754
14755     m_errorMonitor->VerifyFound();
14756 }
14757
14758 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
14759     TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
14760                      "shaders for the same stage");
14761     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14762                                          "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
14763
14764     ASSERT_NO_FATAL_FAILURE(InitState());
14765     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14766
14767     char const *vsSource = "#version 450\n"
14768                            "\n"
14769                            "out gl_PerVertex {\n"
14770                            "    vec4 gl_Position;\n"
14771                            "};\n"
14772                            "void main(){\n"
14773                            "   gl_Position = vec4(1);\n"
14774                            "}\n";
14775     char const *fsSource = "#version 450\n"
14776                            "\n"
14777                            "layout(location=0) out vec4 color;\n"
14778                            "void main(){\n"
14779                            "   color = vec4(1);\n"
14780                            "}\n";
14781
14782     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14783     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14784
14785     VkPipelineObj pipe(m_device);
14786     pipe.AddColorAttachment();
14787     pipe.AddShader(&vs);
14788     pipe.AddShader(&vs);
14789     pipe.AddShader(&fs);
14790
14791     VkDescriptorSetObj descriptorSet(m_device);
14792     descriptorSet.AppendDummy();
14793     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14794
14795     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14796
14797     m_errorMonitor->VerifyFound();
14798 }
14799
14800 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
14801     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
14802                      "as vertex attributes");
14803     m_errorMonitor->ExpectSuccess();
14804
14805     ASSERT_NO_FATAL_FAILURE(InitState());
14806     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14807
14808     VkVertexInputBindingDescription input_binding;
14809     memset(&input_binding, 0, sizeof(input_binding));
14810
14811     VkVertexInputAttributeDescription input_attribs[2];
14812     memset(input_attribs, 0, sizeof(input_attribs));
14813
14814     for (int i = 0; i < 2; i++) {
14815         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14816         input_attribs[i].location = i;
14817     }
14818
14819     char const *vsSource = "#version 450\n"
14820                            "\n"
14821                            "layout(location=0) in mat2x4 x;\n"
14822                            "out gl_PerVertex {\n"
14823                            "    vec4 gl_Position;\n"
14824                            "};\n"
14825                            "void main(){\n"
14826                            "   gl_Position = x[0] + x[1];\n"
14827                            "}\n";
14828     char const *fsSource = "#version 450\n"
14829                            "\n"
14830                            "layout(location=0) out vec4 color;\n"
14831                            "void main(){\n"
14832                            "   color = vec4(1);\n"
14833                            "}\n";
14834
14835     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14836     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14837
14838     VkPipelineObj pipe(m_device);
14839     pipe.AddColorAttachment();
14840     pipe.AddShader(&vs);
14841     pipe.AddShader(&fs);
14842
14843     pipe.AddVertexInputBindings(&input_binding, 1);
14844     pipe.AddVertexInputAttribs(input_attribs, 2);
14845
14846     VkDescriptorSetObj descriptorSet(m_device);
14847     descriptorSet.AppendDummy();
14848     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14849
14850     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14851
14852     /* expect success */
14853     m_errorMonitor->VerifyNotFound();
14854 }
14855
14856 TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
14857     m_errorMonitor->ExpectSuccess();
14858
14859     ASSERT_NO_FATAL_FAILURE(InitState());
14860     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14861
14862     VkVertexInputBindingDescription input_binding;
14863     memset(&input_binding, 0, sizeof(input_binding));
14864
14865     VkVertexInputAttributeDescription input_attribs[2];
14866     memset(input_attribs, 0, sizeof(input_attribs));
14867
14868     for (int i = 0; i < 2; i++) {
14869         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14870         input_attribs[i].location = i;
14871     }
14872
14873     char const *vsSource = "#version 450\n"
14874                            "\n"
14875                            "layout(location=0) in vec4 x[2];\n"
14876                            "out gl_PerVertex {\n"
14877                            "    vec4 gl_Position;\n"
14878                            "};\n"
14879                            "void main(){\n"
14880                            "   gl_Position = x[0] + x[1];\n"
14881                            "}\n";
14882     char const *fsSource = "#version 450\n"
14883                            "\n"
14884                            "layout(location=0) out vec4 color;\n"
14885                            "void main(){\n"
14886                            "   color = vec4(1);\n"
14887                            "}\n";
14888
14889     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14890     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14891
14892     VkPipelineObj pipe(m_device);
14893     pipe.AddColorAttachment();
14894     pipe.AddShader(&vs);
14895     pipe.AddShader(&fs);
14896
14897     pipe.AddVertexInputBindings(&input_binding, 1);
14898     pipe.AddVertexInputAttribs(input_attribs, 2);
14899
14900     VkDescriptorSetObj descriptorSet(m_device);
14901     descriptorSet.AppendDummy();
14902     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14903
14904     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14905
14906     m_errorMonitor->VerifyNotFound();
14907 }
14908
14909 TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
14910     TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
14911                      "through multiple vertex shader inputs, each consuming a different "
14912                      "subset of the components.");
14913     m_errorMonitor->ExpectSuccess();
14914
14915     ASSERT_NO_FATAL_FAILURE(InitState());
14916     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14917
14918     VkVertexInputBindingDescription input_binding;
14919     memset(&input_binding, 0, sizeof(input_binding));
14920
14921     VkVertexInputAttributeDescription input_attribs[3];
14922     memset(input_attribs, 0, sizeof(input_attribs));
14923
14924     for (int i = 0; i < 3; i++) {
14925         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14926         input_attribs[i].location = i;
14927     }
14928
14929     char const *vsSource = "#version 450\n"
14930                            "\n"
14931                            "layout(location=0) in vec4 x;\n"
14932                            "layout(location=1) in vec3 y1;\n"
14933                            "layout(location=1, component=3) in float y2;\n"
14934                            "layout(location=2) in vec4 z;\n"
14935                            "out gl_PerVertex {\n"
14936                            "    vec4 gl_Position;\n"
14937                            "};\n"
14938                            "void main(){\n"
14939                            "   gl_Position = x + vec4(y1, y2) + z;\n"
14940                            "}\n";
14941     char const *fsSource = "#version 450\n"
14942                            "\n"
14943                            "layout(location=0) out vec4 color;\n"
14944                            "void main(){\n"
14945                            "   color = vec4(1);\n"
14946                            "}\n";
14947
14948     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14949     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14950
14951     VkPipelineObj pipe(m_device);
14952     pipe.AddColorAttachment();
14953     pipe.AddShader(&vs);
14954     pipe.AddShader(&fs);
14955
14956     pipe.AddVertexInputBindings(&input_binding, 1);
14957     pipe.AddVertexInputAttribs(input_attribs, 3);
14958
14959     VkDescriptorSetObj descriptorSet(m_device);
14960     descriptorSet.AppendDummy();
14961     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14962
14963     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14964
14965     m_errorMonitor->VerifyNotFound();
14966 }
14967
14968 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
14969     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14970                                          "No entrypoint found named `foo`");
14971
14972     ASSERT_NO_FATAL_FAILURE(InitState());
14973     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14974
14975     char const *vsSource = "#version 450\n"
14976                            "out gl_PerVertex {\n"
14977                            "    vec4 gl_Position;\n"
14978                            "};\n"
14979                            "void main(){\n"
14980                            "   gl_Position = vec4(0);\n"
14981                            "}\n";
14982     char const *fsSource = "#version 450\n"
14983                            "\n"
14984                            "layout(location=0) out vec4 color;\n"
14985                            "void main(){\n"
14986                            "   color = vec4(1);\n"
14987                            "}\n";
14988
14989     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14990     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
14991
14992     VkPipelineObj pipe(m_device);
14993     pipe.AddColorAttachment();
14994     pipe.AddShader(&vs);
14995     pipe.AddShader(&fs);
14996
14997     VkDescriptorSetObj descriptorSet(m_device);
14998     descriptorSet.AppendDummy();
14999     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15000
15001     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15002
15003     m_errorMonitor->VerifyFound();
15004 }
15005
15006 TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
15007     m_errorMonitor->ExpectSuccess();
15008
15009     ASSERT_NO_FATAL_FAILURE(InitState());
15010     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15011
15012     char const *vsSource = "#version 450\n"
15013                            "out gl_PerVertex {\n"
15014                            "    vec4 gl_Position;\n"
15015                            "};\n"
15016                            "void main(){\n"
15017                            "   gl_Position = vec4(0);\n"
15018                            "}\n";
15019     char const *fsSource = "#version 450\n"
15020                            "\n"
15021                            "layout(location=0) out vec4 color;\n"
15022                            "void main(){\n"
15023                            "   color = vec4(1);\n"
15024                            "}\n";
15025
15026     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15027     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15028
15029     VkPipelineObj pipe(m_device);
15030     pipe.AddColorAttachment();
15031     pipe.AddShader(&vs);
15032     pipe.AddShader(&fs);
15033
15034     VkDescriptorSetObj descriptorSet(m_device);
15035     descriptorSet.AppendDummy();
15036     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15037
15038     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15039
15040     m_errorMonitor->VerifyNotFound();
15041 }
15042
15043 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
15044     m_errorMonitor->SetDesiredFailureMsg(
15045         VK_DEBUG_REPORT_ERROR_BIT_EXT,
15046         "pDepthStencilState is NULL when rasterization is enabled and subpass "
15047         "uses a depth/stencil attachment");
15048
15049     ASSERT_NO_FATAL_FAILURE(InitState());
15050     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15051
15052     char const *vsSource = "#version 450\n"
15053                            "void main(){ gl_Position = vec4(0); }\n";
15054     char const *fsSource = "#version 450\n"
15055                            "\n"
15056                            "layout(location=0) out vec4 color;\n"
15057                            "void main(){\n"
15058                            "   color = vec4(1);\n"
15059                            "}\n";
15060
15061     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15062     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15063
15064     VkPipelineObj pipe(m_device);
15065     pipe.AddColorAttachment();
15066     pipe.AddShader(&vs);
15067     pipe.AddShader(&fs);
15068
15069     VkDescriptorSetObj descriptorSet(m_device);
15070     descriptorSet.AppendDummy();
15071     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15072
15073     VkAttachmentDescription attachments[] = {
15074         { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
15075           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15076           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15077           VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15078         },
15079         { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT,
15080           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15081           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15082           VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
15083         },
15084     };
15085     VkAttachmentReference refs[] = {
15086         { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
15087         { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL },
15088     };
15089     VkSubpassDescription subpass = {
15090         0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
15091         1, &refs[0], nullptr, &refs[1],
15092         0, nullptr
15093     };
15094     VkRenderPassCreateInfo rpci = {
15095         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
15096         0, 2, attachments, 1, &subpass, 0, nullptr
15097     };
15098     VkRenderPass rp;
15099     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15100     ASSERT_VK_SUCCESS(err);
15101
15102     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
15103
15104     m_errorMonitor->VerifyFound();
15105
15106     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15107 }
15108
15109 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
15110     TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
15111                      "set out in 14.1.3: fundamental type must match, and producer side must "
15112                      "have at least as many components");
15113     m_errorMonitor->ExpectSuccess();
15114
15115     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
15116
15117     ASSERT_NO_FATAL_FAILURE(InitState());
15118     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15119
15120     char const *vsSource = "#version 450\n"
15121                            "out gl_PerVertex {\n"
15122                            "    vec4 gl_Position;\n"
15123                            "};\n"
15124                            "layout(location=0) out vec3 x;\n"
15125                            "layout(location=1) out ivec3 y;\n"
15126                            "layout(location=2) out vec3 z;\n"
15127                            "void main(){\n"
15128                            "   gl_Position = vec4(0);\n"
15129                            "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
15130                            "}\n";
15131     char const *fsSource = "#version 450\n"
15132                            "\n"
15133                            "layout(location=0) out vec4 color;\n"
15134                            "layout(location=0) in float x;\n"
15135                            "layout(location=1) flat in int y;\n"
15136                            "layout(location=2) in vec2 z;\n"
15137                            "void main(){\n"
15138                            "   color = vec4(1 + x + y + z.x);\n"
15139                            "}\n";
15140
15141     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15142     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15143
15144     VkPipelineObj pipe(m_device);
15145     pipe.AddColorAttachment();
15146     pipe.AddShader(&vs);
15147     pipe.AddShader(&fs);
15148
15149     VkDescriptorSetObj descriptorSet(m_device);
15150     descriptorSet.AppendDummy();
15151     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15152
15153     VkResult err = VK_SUCCESS;
15154     err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15155     ASSERT_VK_SUCCESS(err);
15156
15157     m_errorMonitor->VerifyNotFound();
15158 }
15159
15160 TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
15161     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
15162                      "passed between the TCS and TES stages");
15163     m_errorMonitor->ExpectSuccess();
15164
15165     ASSERT_NO_FATAL_FAILURE(InitState());
15166     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15167
15168     if (!m_device->phy().features().tessellationShader) {
15169         printf("Device does not support tessellation shaders; skipped.\n");
15170         return;
15171     }
15172
15173     char const *vsSource = "#version 450\n"
15174                            "void main(){}\n";
15175     char const *tcsSource = "#version 450\n"
15176                             "layout(location=0) out int x[];\n"
15177                             "layout(vertices=3) out;\n"
15178                             "void main(){\n"
15179                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15180                             "   gl_TessLevelInner[0] = 1;\n"
15181                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15182                             "}\n";
15183     char const *tesSource = "#version 450\n"
15184                             "layout(triangles, equal_spacing, cw) in;\n"
15185                             "layout(location=0) in int x[];\n"
15186                             "out gl_PerVertex { vec4 gl_Position; };\n"
15187                             "void main(){\n"
15188                             "   gl_Position.xyz = gl_TessCoord;\n"
15189                             "   gl_Position.w = x[0] + x[1] + x[2];\n"
15190                             "}\n";
15191     char const *fsSource = "#version 450\n"
15192                            "layout(location=0) out vec4 color;\n"
15193                            "void main(){\n"
15194                            "   color = vec4(1);\n"
15195                            "}\n";
15196
15197     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15198     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15199     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15200     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15201
15202     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15203                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15204
15205     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15206
15207     VkPipelineObj pipe(m_device);
15208     pipe.SetInputAssembly(&iasci);
15209     pipe.SetTessellation(&tsci);
15210     pipe.AddColorAttachment();
15211     pipe.AddShader(&vs);
15212     pipe.AddShader(&tcs);
15213     pipe.AddShader(&tes);
15214     pipe.AddShader(&fs);
15215
15216     VkDescriptorSetObj descriptorSet(m_device);
15217     descriptorSet.AppendDummy();
15218     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15219
15220     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15221
15222     m_errorMonitor->VerifyNotFound();
15223 }
15224
15225 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
15226     TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
15227                      "interface block passed into the geometry shader. This "
15228                      "is interesting because the 'extra' array level is not "
15229                      "present on the member type, but on the block instance.");
15230     m_errorMonitor->ExpectSuccess();
15231
15232     ASSERT_NO_FATAL_FAILURE(InitState());
15233     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15234
15235     if (!m_device->phy().features().geometryShader) {
15236         printf("Device does not support geometry shaders; skipped.\n");
15237         return;
15238     }
15239
15240     char const *vsSource = "#version 450\n"
15241                            "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
15242                            "void main(){\n"
15243                            "   vs_out.x = vec4(1);\n"
15244                            "}\n";
15245     char const *gsSource = "#version 450\n"
15246                            "layout(triangles) in;\n"
15247                            "layout(triangle_strip, max_vertices=3) out;\n"
15248                            "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
15249                            "out gl_PerVertex { vec4 gl_Position; };\n"
15250                            "void main() {\n"
15251                            "   gl_Position = gs_in[0].x;\n"
15252                            "   EmitVertex();\n"
15253                            "}\n";
15254     char const *fsSource = "#version 450\n"
15255                            "layout(location=0) out vec4 color;\n"
15256                            "void main(){\n"
15257                            "   color = vec4(1);\n"
15258                            "}\n";
15259
15260     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15261     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
15262     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15263
15264     VkPipelineObj pipe(m_device);
15265     pipe.AddColorAttachment();
15266     pipe.AddShader(&vs);
15267     pipe.AddShader(&gs);
15268     pipe.AddShader(&fs);
15269
15270     VkDescriptorSetObj descriptorSet(m_device);
15271     descriptorSet.AppendDummy();
15272     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15273
15274     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15275
15276     m_errorMonitor->VerifyNotFound();
15277 }
15278
15279 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
15280     TEST_DESCRIPTION("Test that an error is produced for a variable output from "
15281                      "the TCS without the patch decoration, but consumed in the TES "
15282                      "with the decoration.");
15283     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage "
15284                                                                         "but per-patch in tessellation evaluation shader stage");
15285
15286     ASSERT_NO_FATAL_FAILURE(InitState());
15287     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15288
15289     if (!m_device->phy().features().tessellationShader) {
15290         printf("Device does not support tessellation shaders; skipped.\n");
15291         return;
15292     }
15293
15294     char const *vsSource = "#version 450\n"
15295                            "void main(){}\n";
15296     char const *tcsSource = "#version 450\n"
15297                             "layout(location=0) out int x[];\n"
15298                             "layout(vertices=3) out;\n"
15299                             "void main(){\n"
15300                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15301                             "   gl_TessLevelInner[0] = 1;\n"
15302                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15303                             "}\n";
15304     char const *tesSource = "#version 450\n"
15305                             "layout(triangles, equal_spacing, cw) in;\n"
15306                             "layout(location=0) patch in int x;\n"
15307                             "out gl_PerVertex { vec4 gl_Position; };\n"
15308                             "void main(){\n"
15309                             "   gl_Position.xyz = gl_TessCoord;\n"
15310                             "   gl_Position.w = x;\n"
15311                             "}\n";
15312     char const *fsSource = "#version 450\n"
15313                            "layout(location=0) out vec4 color;\n"
15314                            "void main(){\n"
15315                            "   color = vec4(1);\n"
15316                            "}\n";
15317
15318     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15319     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15320     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15321     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15322
15323     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15324                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15325
15326     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15327
15328     VkPipelineObj pipe(m_device);
15329     pipe.SetInputAssembly(&iasci);
15330     pipe.SetTessellation(&tsci);
15331     pipe.AddColorAttachment();
15332     pipe.AddShader(&vs);
15333     pipe.AddShader(&tcs);
15334     pipe.AddShader(&tes);
15335     pipe.AddShader(&fs);
15336
15337     VkDescriptorSetObj descriptorSet(m_device);
15338     descriptorSet.AppendDummy();
15339     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15340
15341     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15342
15343     m_errorMonitor->VerifyFound();
15344 }
15345
15346 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
15347     TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
15348                      "bindings provide the same location");
15349     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15350                                          "Duplicate vertex input binding descriptions for binding 0");
15351
15352     ASSERT_NO_FATAL_FAILURE(InitState());
15353     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15354
15355     /* Two binding descriptions for binding 0 */
15356     VkVertexInputBindingDescription input_bindings[2];
15357     memset(input_bindings, 0, sizeof(input_bindings));
15358
15359     VkVertexInputAttributeDescription input_attrib;
15360     memset(&input_attrib, 0, sizeof(input_attrib));
15361     input_attrib.format = VK_FORMAT_R32_SFLOAT;
15362
15363     char const *vsSource = "#version 450\n"
15364                            "\n"
15365                            "layout(location=0) in float x;\n" /* attrib provided float */
15366                            "out gl_PerVertex {\n"
15367                            "    vec4 gl_Position;\n"
15368                            "};\n"
15369                            "void main(){\n"
15370                            "   gl_Position = vec4(x);\n"
15371                            "}\n";
15372     char const *fsSource = "#version 450\n"
15373                            "\n"
15374                            "layout(location=0) out vec4 color;\n"
15375                            "void main(){\n"
15376                            "   color = vec4(1);\n"
15377                            "}\n";
15378
15379     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15380     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15381
15382     VkPipelineObj pipe(m_device);
15383     pipe.AddColorAttachment();
15384     pipe.AddShader(&vs);
15385     pipe.AddShader(&fs);
15386
15387     pipe.AddVertexInputBindings(input_bindings, 2);
15388     pipe.AddVertexInputAttribs(&input_attrib, 1);
15389
15390     VkDescriptorSetObj descriptorSet(m_device);
15391     descriptorSet.AppendDummy();
15392     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15393
15394     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15395
15396     m_errorMonitor->VerifyFound();
15397 }
15398
15399 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
15400     TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
15401                      "attributes. This is interesting because they consume multiple "
15402                      "locations.");
15403     m_errorMonitor->ExpectSuccess();
15404
15405     ASSERT_NO_FATAL_FAILURE(InitState());
15406     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15407
15408     if (!m_device->phy().features().shaderFloat64) {
15409         printf("Device does not support 64bit vertex attributes; skipped.\n");
15410         return;
15411     }
15412
15413     VkVertexInputBindingDescription input_bindings[1];
15414     memset(input_bindings, 0, sizeof(input_bindings));
15415
15416     VkVertexInputAttributeDescription input_attribs[4];
15417     memset(input_attribs, 0, sizeof(input_attribs));
15418     input_attribs[0].location = 0;
15419     input_attribs[0].offset = 0;
15420     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15421     input_attribs[1].location = 2;
15422     input_attribs[1].offset = 32;
15423     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15424     input_attribs[2].location = 4;
15425     input_attribs[2].offset = 64;
15426     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15427     input_attribs[3].location = 6;
15428     input_attribs[3].offset = 96;
15429     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15430
15431     char const *vsSource = "#version 450\n"
15432                            "\n"
15433                            "layout(location=0) in dmat4 x;\n"
15434                            "out gl_PerVertex {\n"
15435                            "    vec4 gl_Position;\n"
15436                            "};\n"
15437                            "void main(){\n"
15438                            "   gl_Position = vec4(x[0][0]);\n"
15439                            "}\n";
15440     char const *fsSource = "#version 450\n"
15441                            "\n"
15442                            "layout(location=0) out vec4 color;\n"
15443                            "void main(){\n"
15444                            "   color = vec4(1);\n"
15445                            "}\n";
15446
15447     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15448     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15449
15450     VkPipelineObj pipe(m_device);
15451     pipe.AddColorAttachment();
15452     pipe.AddShader(&vs);
15453     pipe.AddShader(&fs);
15454
15455     pipe.AddVertexInputBindings(input_bindings, 1);
15456     pipe.AddVertexInputAttribs(input_attribs, 4);
15457
15458     VkDescriptorSetObj descriptorSet(m_device);
15459     descriptorSet.AppendDummy();
15460     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15461
15462     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15463
15464     m_errorMonitor->VerifyNotFound();
15465 }
15466
15467 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
15468     TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
15469                      "provide an output for one of the pipeline's color attachments");
15470     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
15471
15472     ASSERT_NO_FATAL_FAILURE(InitState());
15473
15474     char const *vsSource = "#version 450\n"
15475                            "\n"
15476                            "out gl_PerVertex {\n"
15477                            "    vec4 gl_Position;\n"
15478                            "};\n"
15479                            "void main(){\n"
15480                            "   gl_Position = vec4(1);\n"
15481                            "}\n";
15482     char const *fsSource = "#version 450\n"
15483                            "\n"
15484                            "void main(){\n"
15485                            "}\n";
15486
15487     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15488     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15489
15490     VkPipelineObj pipe(m_device);
15491     pipe.AddShader(&vs);
15492     pipe.AddShader(&fs);
15493
15494     /* set up CB 0, not written */
15495     pipe.AddColorAttachment();
15496     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15497
15498     VkDescriptorSetObj descriptorSet(m_device);
15499     descriptorSet.AppendDummy();
15500     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15501
15502     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15503
15504     m_errorMonitor->VerifyFound();
15505 }
15506
15507 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
15508     TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
15509                      "output with no matching attachment");
15510     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
15511                                          "FS writes to output location 1 with no matching attachment");
15512
15513     ASSERT_NO_FATAL_FAILURE(InitState());
15514
15515     char const *vsSource = "#version 450\n"
15516                            "\n"
15517                            "out gl_PerVertex {\n"
15518                            "    vec4 gl_Position;\n"
15519                            "};\n"
15520                            "void main(){\n"
15521                            "   gl_Position = vec4(1);\n"
15522                            "}\n";
15523     char const *fsSource = "#version 450\n"
15524                            "\n"
15525                            "layout(location=0) out vec4 x;\n"
15526                            "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
15527                            "void main(){\n"
15528                            "   x = vec4(1);\n"
15529                            "   y = vec4(1);\n"
15530                            "}\n";
15531
15532     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15533     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15534
15535     VkPipelineObj pipe(m_device);
15536     pipe.AddShader(&vs);
15537     pipe.AddShader(&fs);
15538
15539     /* set up CB 0, not written */
15540     pipe.AddColorAttachment();
15541     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15542     /* FS writes CB 1, but we don't configure it */
15543
15544     VkDescriptorSetObj descriptorSet(m_device);
15545     descriptorSet.AppendDummy();
15546     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15547
15548     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15549
15550     m_errorMonitor->VerifyFound();
15551 }
15552
15553 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
15554     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
15555                      "type of an FS output variable, and the format of the corresponding attachment");
15556     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
15557
15558     ASSERT_NO_FATAL_FAILURE(InitState());
15559
15560     char const *vsSource = "#version 450\n"
15561                            "\n"
15562                            "out gl_PerVertex {\n"
15563                            "    vec4 gl_Position;\n"
15564                            "};\n"
15565                            "void main(){\n"
15566                            "   gl_Position = vec4(1);\n"
15567                            "}\n";
15568     char const *fsSource = "#version 450\n"
15569                            "\n"
15570                            "layout(location=0) out ivec4 x;\n" /* not UNORM */
15571                            "void main(){\n"
15572                            "   x = ivec4(1);\n"
15573                            "}\n";
15574
15575     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15576     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15577
15578     VkPipelineObj pipe(m_device);
15579     pipe.AddShader(&vs);
15580     pipe.AddShader(&fs);
15581
15582     /* set up CB 0; type is UNORM by default */
15583     pipe.AddColorAttachment();
15584     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15585
15586     VkDescriptorSetObj descriptorSet(m_device);
15587     descriptorSet.AppendDummy();
15588     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15589
15590     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15591
15592     m_errorMonitor->VerifyFound();
15593 }
15594
15595 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
15596     TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
15597                      "block which has no corresponding binding in the pipeline layout");
15598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
15599
15600     ASSERT_NO_FATAL_FAILURE(InitState());
15601
15602     char const *vsSource = "#version 450\n"
15603                            "\n"
15604                            "out gl_PerVertex {\n"
15605                            "    vec4 gl_Position;\n"
15606                            "};\n"
15607                            "void main(){\n"
15608                            "   gl_Position = vec4(1);\n"
15609                            "}\n";
15610     char const *fsSource = "#version 450\n"
15611                            "\n"
15612                            "layout(location=0) out vec4 x;\n"
15613                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
15614                            "void main(){\n"
15615                            "   x = vec4(bar.y);\n"
15616                            "}\n";
15617
15618     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15619     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15620
15621     VkPipelineObj pipe(m_device);
15622     pipe.AddShader(&vs);
15623     pipe.AddShader(&fs);
15624
15625     /* set up CB 0; type is UNORM by default */
15626     pipe.AddColorAttachment();
15627     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15628
15629     VkDescriptorSetObj descriptorSet(m_device);
15630     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15631
15632     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15633
15634     m_errorMonitor->VerifyFound();
15635 }
15636
15637 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
15638     TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
15639                      "which are not provided in the pipeline layout");
15640     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
15641
15642     ASSERT_NO_FATAL_FAILURE(InitState());
15643
15644     char const *vsSource = "#version 450\n"
15645                            "\n"
15646                            "layout(push_constant, std430) uniform foo { float x; } consts;\n"
15647                            "out gl_PerVertex {\n"
15648                            "    vec4 gl_Position;\n"
15649                            "};\n"
15650                            "void main(){\n"
15651                            "   gl_Position = vec4(consts.x);\n"
15652                            "}\n";
15653     char const *fsSource = "#version 450\n"
15654                            "\n"
15655                            "layout(location=0) out vec4 x;\n"
15656                            "void main(){\n"
15657                            "   x = vec4(1);\n"
15658                            "}\n";
15659
15660     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15661     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15662
15663     VkPipelineObj pipe(m_device);
15664     pipe.AddShader(&vs);
15665     pipe.AddShader(&fs);
15666
15667     /* set up CB 0; type is UNORM by default */
15668     pipe.AddColorAttachment();
15669     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15670
15671     VkDescriptorSetObj descriptorSet(m_device);
15672     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15673
15674     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15675
15676     /* should have generated an error -- no push constant ranges provided! */
15677     m_errorMonitor->VerifyFound();
15678 }
15679
15680 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
15681     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15682                      "which is not included in the subpass description");
15683     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15684                                          "consumes input attachment index 0 but not provided in subpass");
15685
15686     ASSERT_NO_FATAL_FAILURE(InitState());
15687
15688     char const *vsSource = "#version 450\n"
15689                            "\n"
15690                            "out gl_PerVertex {\n"
15691                            "    vec4 gl_Position;\n"
15692                            "};\n"
15693                            "void main(){\n"
15694                            "    gl_Position = vec4(1);\n"
15695                            "}\n";
15696     char const *fsSource = "#version 450\n"
15697                            "\n"
15698                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15699                            "layout(location=0) out vec4 color;\n"
15700                            "void main() {\n"
15701                            "   color = subpassLoad(x);\n"
15702                            "}\n";
15703
15704     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15705     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15706
15707     VkPipelineObj pipe(m_device);
15708     pipe.AddShader(&vs);
15709     pipe.AddShader(&fs);
15710     pipe.AddColorAttachment();
15711     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15712
15713     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15714     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15715     VkDescriptorSetLayout dsl;
15716     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15717     ASSERT_VK_SUCCESS(err);
15718
15719     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15720     VkPipelineLayout pl;
15721     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15722     ASSERT_VK_SUCCESS(err);
15723
15724     // error here.
15725     pipe.CreateVKPipeline(pl, renderPass());
15726
15727     m_errorMonitor->VerifyFound();
15728
15729     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15730     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15731 }
15732
15733 TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
15734     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
15735     m_errorMonitor->ExpectSuccess();
15736
15737     ASSERT_NO_FATAL_FAILURE(InitState());
15738
15739     char const *vsSource = "#version 450\n"
15740                            "\n"
15741                            "out gl_PerVertex {\n"
15742                            "    vec4 gl_Position;\n"
15743                            "};\n"
15744                            "void main(){\n"
15745                            "    gl_Position = vec4(1);\n"
15746                            "}\n";
15747     char const *fsSource = "#version 450\n"
15748                            "\n"
15749                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15750                            "layout(location=0) out vec4 color;\n"
15751                            "void main() {\n"
15752                            "   color = subpassLoad(x);\n"
15753                            "}\n";
15754
15755     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15756     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15757
15758     VkPipelineObj pipe(m_device);
15759     pipe.AddShader(&vs);
15760     pipe.AddShader(&fs);
15761     pipe.AddColorAttachment();
15762     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15763
15764     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15765     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15766     VkDescriptorSetLayout dsl;
15767     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15768     ASSERT_VK_SUCCESS(err);
15769
15770     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15771     VkPipelineLayout pl;
15772     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15773     ASSERT_VK_SUCCESS(err);
15774
15775     VkAttachmentDescription descs[2] = {
15776         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15777          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15778          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15779         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15780          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15781     };
15782     VkAttachmentReference color = {
15783         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15784     };
15785     VkAttachmentReference input = {
15786         1, VK_IMAGE_LAYOUT_GENERAL,
15787     };
15788
15789     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15790
15791     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15792     VkRenderPass rp;
15793     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15794     ASSERT_VK_SUCCESS(err);
15795
15796     // should be OK. would go wrong here if it's going to...
15797     pipe.CreateVKPipeline(pl, rp);
15798
15799     m_errorMonitor->VerifyNotFound();
15800
15801     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15802     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15803     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15804 }
15805
15806 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
15807     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15808                      "with a format having a different fundamental type");
15809     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15810                                          "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
15811
15812     ASSERT_NO_FATAL_FAILURE(InitState());
15813
15814     char const *vsSource = "#version 450\n"
15815                            "\n"
15816                            "out gl_PerVertex {\n"
15817                            "    vec4 gl_Position;\n"
15818                            "};\n"
15819                            "void main(){\n"
15820                            "    gl_Position = vec4(1);\n"
15821                            "}\n";
15822     char const *fsSource = "#version 450\n"
15823                            "\n"
15824                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15825                            "layout(location=0) out vec4 color;\n"
15826                            "void main() {\n"
15827                            "   color = subpassLoad(x);\n"
15828                            "}\n";
15829
15830     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15831     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15832
15833     VkPipelineObj pipe(m_device);
15834     pipe.AddShader(&vs);
15835     pipe.AddShader(&fs);
15836     pipe.AddColorAttachment();
15837     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15838
15839     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15840     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15841     VkDescriptorSetLayout dsl;
15842     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15843     ASSERT_VK_SUCCESS(err);
15844
15845     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15846     VkPipelineLayout pl;
15847     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15848     ASSERT_VK_SUCCESS(err);
15849
15850     VkAttachmentDescription descs[2] = {
15851         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15852          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15853          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15854         {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15855          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15856     };
15857     VkAttachmentReference color = {
15858         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15859     };
15860     VkAttachmentReference input = {
15861         1, VK_IMAGE_LAYOUT_GENERAL,
15862     };
15863
15864     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15865
15866     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15867     VkRenderPass rp;
15868     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15869     ASSERT_VK_SUCCESS(err);
15870
15871     // error here.
15872     pipe.CreateVKPipeline(pl, rp);
15873
15874     m_errorMonitor->VerifyFound();
15875
15876     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15877     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15878     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15879 }
15880
15881 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
15882     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15883                      "which is not included in the subpass description -- array case");
15884     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15885                                          "consumes input attachment index 1 but not provided in subpass");
15886
15887     ASSERT_NO_FATAL_FAILURE(InitState());
15888
15889     char const *vsSource = "#version 450\n"
15890                            "\n"
15891                            "out gl_PerVertex {\n"
15892                            "    vec4 gl_Position;\n"
15893                            "};\n"
15894                            "void main(){\n"
15895                            "    gl_Position = vec4(1);\n"
15896                            "}\n";
15897     char const *fsSource = "#version 450\n"
15898                            "\n"
15899                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n"
15900                            "layout(location=0) out vec4 color;\n"
15901                            "void main() {\n"
15902                            "   color = subpassLoad(xs[1]);\n"
15903                            "}\n";
15904
15905     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15906     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15907
15908     VkPipelineObj pipe(m_device);
15909     pipe.AddShader(&vs);
15910     pipe.AddShader(&fs);
15911     pipe.AddColorAttachment();
15912     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15913
15914     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15915     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15916     VkDescriptorSetLayout dsl;
15917     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15918     ASSERT_VK_SUCCESS(err);
15919
15920     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15921     VkPipelineLayout pl;
15922     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15923     ASSERT_VK_SUCCESS(err);
15924
15925     // error here.
15926     pipe.CreateVKPipeline(pl, renderPass());
15927
15928     m_errorMonitor->VerifyFound();
15929
15930     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15931     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15932 }
15933
15934 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
15935     TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
15936                      "descriptor which is not provided in the pipeline layout");
15937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
15938
15939     ASSERT_NO_FATAL_FAILURE(InitState());
15940
15941     char const *csSource = "#version 450\n"
15942                            "\n"
15943                            "layout(local_size_x=1) in;\n"
15944                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15945                            "void main(){\n"
15946                            "   x = vec4(1);\n"
15947                            "}\n";
15948
15949     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15950
15951     VkDescriptorSetObj descriptorSet(m_device);
15952     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15953
15954     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15955                                         nullptr,
15956                                         0,
15957                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15958                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15959                                         descriptorSet.GetPipelineLayout(),
15960                                         VK_NULL_HANDLE,
15961                                         -1};
15962
15963     VkPipeline pipe;
15964     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
15965
15966     m_errorMonitor->VerifyFound();
15967
15968     if (err == VK_SUCCESS) {
15969         vkDestroyPipeline(m_device->device(), pipe, nullptr);
15970     }
15971 }
15972
15973 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
15974     TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
15975                      "descriptor-backed resource which is not provided, but the shader does not "
15976                      "statically use it. This is interesting because it requires compute pipelines "
15977                      "to have a proper descriptor use walk, which they didn't for some time.");
15978     m_errorMonitor->ExpectSuccess();
15979
15980     ASSERT_NO_FATAL_FAILURE(InitState());
15981
15982     char const *csSource = "#version 450\n"
15983                            "\n"
15984                            "layout(local_size_x=1) in;\n"
15985                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15986                            "void main(){\n"
15987                            "   // x is not used.\n"
15988                            "}\n";
15989
15990     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15991
15992     VkDescriptorSetObj descriptorSet(m_device);
15993     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15994
15995     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15996                                         nullptr,
15997                                         0,
15998                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15999                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16000                                         descriptorSet.GetPipelineLayout(),
16001                                         VK_NULL_HANDLE,
16002                                         -1};
16003
16004     VkPipeline pipe;
16005     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16006
16007     m_errorMonitor->VerifyNotFound();
16008
16009     if (err == VK_SUCCESS) {
16010         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16011     }
16012 }
16013
16014 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
16015     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
16016                      "descriptor-backed resource of a mismatched type");
16017     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16018                                          "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
16019
16020     ASSERT_NO_FATAL_FAILURE(InitState());
16021
16022     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
16023     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding};
16024     VkDescriptorSetLayout dsl;
16025     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16026     ASSERT_VK_SUCCESS(err);
16027
16028     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16029     VkPipelineLayout pl;
16030     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16031     ASSERT_VK_SUCCESS(err);
16032
16033     char const *csSource = "#version 450\n"
16034                            "\n"
16035                            "layout(local_size_x=1) in;\n"
16036                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
16037                            "void main() {\n"
16038                            "   x.x = 1.0f;\n"
16039                            "}\n";
16040     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16041
16042     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16043                                         nullptr,
16044                                         0,
16045                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16046                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16047                                         pl,
16048                                         VK_NULL_HANDLE,
16049                                         -1};
16050
16051     VkPipeline pipe;
16052     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16053
16054     m_errorMonitor->VerifyFound();
16055
16056     if (err == VK_SUCCESS) {
16057         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16058     }
16059
16060     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16061     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16062 }
16063
16064 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
16065     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16066                      "sampler portion of a combined image + sampler");
16067     m_errorMonitor->ExpectSuccess();
16068
16069     ASSERT_NO_FATAL_FAILURE(InitState());
16070
16071     VkDescriptorSetLayoutBinding bindings[] = {
16072         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16073         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16074         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16075     };
16076     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16077     VkDescriptorSetLayout dsl;
16078     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16079     ASSERT_VK_SUCCESS(err);
16080
16081     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16082     VkPipelineLayout pl;
16083     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16084     ASSERT_VK_SUCCESS(err);
16085
16086     char const *csSource = "#version 450\n"
16087                            "\n"
16088                            "layout(local_size_x=1) in;\n"
16089                            "layout(set=0, binding=0) uniform sampler s;\n"
16090                            "layout(set=0, binding=1) uniform texture2D t;\n"
16091                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16092                            "void main() {\n"
16093                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16094                            "}\n";
16095     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16096
16097     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16098                                         nullptr,
16099                                         0,
16100                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16101                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16102                                         pl,
16103                                         VK_NULL_HANDLE,
16104                                         -1};
16105
16106     VkPipeline pipe;
16107     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16108
16109     m_errorMonitor->VerifyNotFound();
16110
16111     if (err == VK_SUCCESS) {
16112         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16113     }
16114
16115     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16116     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16117 }
16118
16119 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
16120     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16121                      "image portion of a combined image + sampler");
16122     m_errorMonitor->ExpectSuccess();
16123
16124     ASSERT_NO_FATAL_FAILURE(InitState());
16125
16126     VkDescriptorSetLayoutBinding bindings[] = {
16127         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16128         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16129         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16130     };
16131     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16132     VkDescriptorSetLayout dsl;
16133     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16134     ASSERT_VK_SUCCESS(err);
16135
16136     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16137     VkPipelineLayout pl;
16138     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16139     ASSERT_VK_SUCCESS(err);
16140
16141     char const *csSource = "#version 450\n"
16142                            "\n"
16143                            "layout(local_size_x=1) in;\n"
16144                            "layout(set=0, binding=0) uniform texture2D t;\n"
16145                            "layout(set=0, binding=1) uniform sampler s;\n"
16146                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16147                            "void main() {\n"
16148                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16149                            "}\n";
16150     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16151
16152     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16153                                         nullptr,
16154                                         0,
16155                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16156                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16157                                         pl,
16158                                         VK_NULL_HANDLE,
16159                                         -1};
16160
16161     VkPipeline pipe;
16162     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16163
16164     m_errorMonitor->VerifyNotFound();
16165
16166     if (err == VK_SUCCESS) {
16167         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16168     }
16169
16170     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16171     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16172 }
16173
16174 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
16175     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
16176                      "both the sampler and the image of a combined image+sampler "
16177                      "but via separate variables");
16178     m_errorMonitor->ExpectSuccess();
16179
16180     ASSERT_NO_FATAL_FAILURE(InitState());
16181
16182     VkDescriptorSetLayoutBinding bindings[] = {
16183         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16184         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16185     };
16186     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
16187     VkDescriptorSetLayout dsl;
16188     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16189     ASSERT_VK_SUCCESS(err);
16190
16191     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16192     VkPipelineLayout pl;
16193     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16194     ASSERT_VK_SUCCESS(err);
16195
16196     char const *csSource = "#version 450\n"
16197                            "\n"
16198                            "layout(local_size_x=1) in;\n"
16199                            "layout(set=0, binding=0) uniform texture2D t;\n"
16200                            "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
16201                            "layout(set=0, binding=1) buffer block { vec4 x; };\n"
16202                            "void main() {\n"
16203                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16204                            "}\n";
16205     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16206
16207     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16208                                         nullptr,
16209                                         0,
16210                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16211                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16212                                         pl,
16213                                         VK_NULL_HANDLE,
16214                                         -1};
16215
16216     VkPipeline pipe;
16217     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16218
16219     m_errorMonitor->VerifyNotFound();
16220
16221     if (err == VK_SUCCESS) {
16222         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16223     }
16224
16225     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16226     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16227 }
16228
16229 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
16230     TEST_DESCRIPTION("Test that an error is produced when an image view type "
16231                      "does not match the dimensionality declared in the shader");
16232
16233     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
16234
16235     ASSERT_NO_FATAL_FAILURE(InitState());
16236     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16237
16238     char const *vsSource = "#version 450\n"
16239                            "\n"
16240                            "out gl_PerVertex { vec4 gl_Position; };\n"
16241                            "void main() { gl_Position = vec4(0); }\n";
16242     char const *fsSource = "#version 450\n"
16243                            "\n"
16244                            "layout(set=0, binding=0) uniform sampler3D s;\n"
16245                            "layout(location=0) out vec4 color;\n"
16246                            "void main() {\n"
16247                            "   color = texture(s, vec3(0));\n"
16248                            "}\n";
16249     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16250     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16251
16252     VkPipelineObj pipe(m_device);
16253     pipe.AddShader(&vs);
16254     pipe.AddShader(&fs);
16255     pipe.AddColorAttachment();
16256
16257     VkTextureObj texture(m_device, nullptr);
16258     VkSamplerObj sampler(m_device);
16259
16260     VkDescriptorSetObj descriptorSet(m_device);
16261     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16262     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16263
16264     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16265     ASSERT_VK_SUCCESS(err);
16266
16267     BeginCommandBuffer();
16268
16269     m_commandBuffer->BindPipeline(pipe);
16270     m_commandBuffer->BindDescriptorSet(descriptorSet);
16271
16272     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16273     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16274     VkRect2D scissor = {{0, 0}, {16, 16}};
16275     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16276
16277     // error produced here.
16278     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16279
16280     m_errorMonitor->VerifyFound();
16281
16282     EndCommandBuffer();
16283 }
16284
16285 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
16286     TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
16287                      "are consumed via singlesample images types in the shader, or vice versa.");
16288
16289     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
16290
16291     ASSERT_NO_FATAL_FAILURE(InitState());
16292     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16293
16294     char const *vsSource = "#version 450\n"
16295                            "\n"
16296                            "out gl_PerVertex { vec4 gl_Position; };\n"
16297                            "void main() { gl_Position = vec4(0); }\n";
16298     char const *fsSource = "#version 450\n"
16299                            "\n"
16300                            "layout(set=0, binding=0) uniform sampler2DMS s;\n"
16301                            "layout(location=0) out vec4 color;\n"
16302                            "void main() {\n"
16303                            "   color = texelFetch(s, ivec2(0), 0);\n"
16304                            "}\n";
16305     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16306     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16307
16308     VkPipelineObj pipe(m_device);
16309     pipe.AddShader(&vs);
16310     pipe.AddShader(&fs);
16311     pipe.AddColorAttachment();
16312
16313     VkTextureObj texture(m_device, nullptr);
16314     VkSamplerObj sampler(m_device);
16315
16316     VkDescriptorSetObj descriptorSet(m_device);
16317     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16318     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16319
16320     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16321     ASSERT_VK_SUCCESS(err);
16322
16323     BeginCommandBuffer();
16324
16325     m_commandBuffer->BindPipeline(pipe);
16326     m_commandBuffer->BindDescriptorSet(descriptorSet);
16327
16328     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16329     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16330     VkRect2D scissor = {{0, 0}, {16, 16}};
16331     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16332
16333     // error produced here.
16334     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16335
16336     m_errorMonitor->VerifyFound();
16337
16338     EndCommandBuffer();
16339 }
16340
16341 #endif // SHADER_CHECKER_TESTS
16342
16343 #if DEVICE_LIMITS_TESTS
16344 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) {
16345     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16346
16347     ASSERT_NO_FATAL_FAILURE(InitState());
16348
16349     // Create an image
16350     VkImage image;
16351
16352     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16353     const int32_t tex_width = 32;
16354     const int32_t tex_height = 32;
16355
16356     VkImageCreateInfo image_create_info = {};
16357     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16358     image_create_info.pNext = NULL;
16359     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16360     image_create_info.format = tex_format;
16361     image_create_info.extent.width = tex_width;
16362     image_create_info.extent.height = tex_height;
16363     image_create_info.extent.depth = 1;
16364     image_create_info.mipLevels = 1;
16365     image_create_info.arrayLayers = 1;
16366     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16367     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16368     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16369     image_create_info.flags = 0;
16370
16371     // Introduce error by sending down a bogus width extent
16372     image_create_info.extent.width = 65536;
16373     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16374
16375     m_errorMonitor->VerifyFound();
16376 }
16377
16378 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) {
16379     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16380                                          "CreateImage extents is 0 for at least one required dimension");
16381
16382     ASSERT_NO_FATAL_FAILURE(InitState());
16383
16384     // Create an image
16385     VkImage image;
16386
16387     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16388     const int32_t tex_width = 32;
16389     const int32_t tex_height = 32;
16390
16391     VkImageCreateInfo image_create_info = {};
16392     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16393     image_create_info.pNext = NULL;
16394     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16395     image_create_info.format = tex_format;
16396     image_create_info.extent.width = tex_width;
16397     image_create_info.extent.height = tex_height;
16398     image_create_info.extent.depth = 1;
16399     image_create_info.mipLevels = 1;
16400     image_create_info.arrayLayers = 1;
16401     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16402     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16403     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16404     image_create_info.flags = 0;
16405
16406     // Introduce error by sending down a bogus width extent
16407     image_create_info.extent.width = 0;
16408     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16409
16410     m_errorMonitor->VerifyFound();
16411 }
16412 #endif // DEVICE_LIMITS_TESTS
16413
16414 #if IMAGE_TESTS
16415 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
16416     TEST_DESCRIPTION("Create a render pass with an attachment description "
16417                      "format set to VK_FORMAT_UNDEFINED");
16418
16419     ASSERT_NO_FATAL_FAILURE(InitState());
16420     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16421
16422     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
16423
16424     VkAttachmentReference color_attach = {};
16425     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
16426     color_attach.attachment = 0;
16427     VkSubpassDescription subpass = {};
16428     subpass.colorAttachmentCount = 1;
16429     subpass.pColorAttachments = &color_attach;
16430
16431     VkRenderPassCreateInfo rpci = {};
16432     rpci.subpassCount = 1;
16433     rpci.pSubpasses = &subpass;
16434     rpci.attachmentCount = 1;
16435     VkAttachmentDescription attach_desc = {};
16436     attach_desc.format = VK_FORMAT_UNDEFINED;
16437     rpci.pAttachments = &attach_desc;
16438     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16439     VkRenderPass rp;
16440     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16441
16442     m_errorMonitor->VerifyFound();
16443
16444     if (result == VK_SUCCESS) {
16445         vkDestroyRenderPass(m_device->device(), rp, NULL);
16446     }
16447 }
16448
16449 TEST_F(VkLayerTest, InvalidImageView) {
16450     VkResult err;
16451
16452     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 ");
16453
16454     ASSERT_NO_FATAL_FAILURE(InitState());
16455
16456     // Create an image and try to create a view with bad baseMipLevel
16457     VkImage image;
16458
16459     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16460     const int32_t tex_width = 32;
16461     const int32_t tex_height = 32;
16462
16463     VkImageCreateInfo image_create_info = {};
16464     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16465     image_create_info.pNext = NULL;
16466     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16467     image_create_info.format = tex_format;
16468     image_create_info.extent.width = tex_width;
16469     image_create_info.extent.height = tex_height;
16470     image_create_info.extent.depth = 1;
16471     image_create_info.mipLevels = 1;
16472     image_create_info.arrayLayers = 1;
16473     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16474     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16475     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16476     image_create_info.flags = 0;
16477
16478     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16479     ASSERT_VK_SUCCESS(err);
16480
16481     VkImageViewCreateInfo image_view_create_info = {};
16482     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16483     image_view_create_info.image = image;
16484     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16485     image_view_create_info.format = tex_format;
16486     image_view_create_info.subresourceRange.layerCount = 1;
16487     image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error
16488     image_view_create_info.subresourceRange.levelCount = 1;
16489     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16490
16491     VkImageView view;
16492     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16493
16494     m_errorMonitor->VerifyFound();
16495     vkDestroyImage(m_device->device(), image, NULL);
16496 }
16497
16498 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
16499     VkResult err;
16500     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16501                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
16502
16503     ASSERT_NO_FATAL_FAILURE(InitState());
16504
16505     // Create an image and try to create a view with no memory backing the image
16506     VkImage image;
16507
16508     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16509     const int32_t tex_width = 32;
16510     const int32_t tex_height = 32;
16511
16512     VkImageCreateInfo image_create_info = {};
16513     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16514     image_create_info.pNext = NULL;
16515     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16516     image_create_info.format = tex_format;
16517     image_create_info.extent.width = tex_width;
16518     image_create_info.extent.height = tex_height;
16519     image_create_info.extent.depth = 1;
16520     image_create_info.mipLevels = 1;
16521     image_create_info.arrayLayers = 1;
16522     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16523     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16524     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16525     image_create_info.flags = 0;
16526
16527     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16528     ASSERT_VK_SUCCESS(err);
16529
16530     VkImageViewCreateInfo image_view_create_info = {};
16531     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16532     image_view_create_info.image = image;
16533     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16534     image_view_create_info.format = tex_format;
16535     image_view_create_info.subresourceRange.layerCount = 1;
16536     image_view_create_info.subresourceRange.baseMipLevel = 0;
16537     image_view_create_info.subresourceRange.levelCount = 1;
16538     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16539
16540     VkImageView view;
16541     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16542
16543     m_errorMonitor->VerifyFound();
16544     vkDestroyImage(m_device->device(), image, NULL);
16545     // If last error is success, it still created the view, so delete it.
16546     if (err == VK_SUCCESS) {
16547         vkDestroyImageView(m_device->device(), view, NULL);
16548     }
16549 }
16550
16551 TEST_F(VkLayerTest, InvalidImageViewAspect) {
16552     TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
16553     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image "
16554                                                                         "formats must have ONLY the "
16555                                                                         "VK_IMAGE_ASPECT_COLOR_BIT set");
16556
16557     ASSERT_NO_FATAL_FAILURE(InitState());
16558
16559     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16560     VkImageObj image(m_device);
16561     image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
16562     ASSERT_TRUE(image.initialized());
16563
16564     VkImageViewCreateInfo image_view_create_info = {};
16565     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16566     image_view_create_info.image = image.handle();
16567     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16568     image_view_create_info.format = tex_format;
16569     image_view_create_info.subresourceRange.baseMipLevel = 0;
16570     image_view_create_info.subresourceRange.levelCount = 1;
16571     // Cause an error by setting an invalid image aspect
16572     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16573
16574     VkImageView view;
16575     vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16576
16577     m_errorMonitor->VerifyFound();
16578 }
16579
16580 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
16581     VkResult err;
16582     bool pass;
16583
16584     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16585                                          "vkCmdCopyImage: number of layers in source and destination subresources for pRegions");
16586
16587     ASSERT_NO_FATAL_FAILURE(InitState());
16588
16589     // Create two images of different types and try to copy between them
16590     VkImage srcImage;
16591     VkImage dstImage;
16592     VkDeviceMemory srcMem;
16593     VkDeviceMemory destMem;
16594     VkMemoryRequirements memReqs;
16595
16596     VkImageCreateInfo image_create_info = {};
16597     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16598     image_create_info.pNext = NULL;
16599     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16600     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16601     image_create_info.extent.width = 32;
16602     image_create_info.extent.height = 32;
16603     image_create_info.extent.depth = 1;
16604     image_create_info.mipLevels = 1;
16605     image_create_info.arrayLayers = 4;
16606     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16607     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16608     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16609     image_create_info.flags = 0;
16610
16611     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
16612     ASSERT_VK_SUCCESS(err);
16613
16614     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
16615     ASSERT_VK_SUCCESS(err);
16616
16617     // Allocate memory
16618     VkMemoryAllocateInfo memAlloc = {};
16619     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16620     memAlloc.pNext = NULL;
16621     memAlloc.allocationSize = 0;
16622     memAlloc.memoryTypeIndex = 0;
16623
16624     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
16625     memAlloc.allocationSize = memReqs.size;
16626     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16627     ASSERT_TRUE(pass);
16628     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
16629     ASSERT_VK_SUCCESS(err);
16630
16631     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
16632     memAlloc.allocationSize = memReqs.size;
16633     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16634     ASSERT_VK_SUCCESS(err);
16635     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
16636     ASSERT_VK_SUCCESS(err);
16637
16638     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
16639     ASSERT_VK_SUCCESS(err);
16640     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
16641     ASSERT_VK_SUCCESS(err);
16642
16643     BeginCommandBuffer();
16644     VkImageCopy copyRegion;
16645     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16646     copyRegion.srcSubresource.mipLevel = 0;
16647     copyRegion.srcSubresource.baseArrayLayer = 0;
16648     copyRegion.srcSubresource.layerCount = 1;
16649     copyRegion.srcOffset.x = 0;
16650     copyRegion.srcOffset.y = 0;
16651     copyRegion.srcOffset.z = 0;
16652     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16653     copyRegion.dstSubresource.mipLevel = 0;
16654     copyRegion.dstSubresource.baseArrayLayer = 0;
16655     // Introduce failure by forcing the dst layerCount to differ from src
16656     copyRegion.dstSubresource.layerCount = 3;
16657     copyRegion.dstOffset.x = 0;
16658     copyRegion.dstOffset.y = 0;
16659     copyRegion.dstOffset.z = 0;
16660     copyRegion.extent.width = 1;
16661     copyRegion.extent.height = 1;
16662     copyRegion.extent.depth = 1;
16663     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
16664     EndCommandBuffer();
16665
16666     m_errorMonitor->VerifyFound();
16667
16668     vkDestroyImage(m_device->device(), srcImage, NULL);
16669     vkDestroyImage(m_device->device(), dstImage, NULL);
16670     vkFreeMemory(m_device->device(), srcMem, NULL);
16671     vkFreeMemory(m_device->device(), destMem, NULL);
16672 }
16673
16674 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
16675
16676     TEST_DESCRIPTION("Creating images with unsuported formats ");
16677
16678     ASSERT_NO_FATAL_FAILURE(InitState());
16679     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16680     VkImageObj image(m_device);
16681     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16682                VK_IMAGE_TILING_OPTIMAL, 0);
16683     ASSERT_TRUE(image.initialized());
16684
16685     // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
16686     VkImageCreateInfo image_create_info;
16687     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16688     image_create_info.pNext = NULL;
16689     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16690     image_create_info.format = VK_FORMAT_UNDEFINED;
16691     image_create_info.extent.width = 32;
16692     image_create_info.extent.height = 32;
16693     image_create_info.extent.depth = 1;
16694     image_create_info.mipLevels = 1;
16695     image_create_info.arrayLayers = 1;
16696     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16697     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16698     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16699     image_create_info.flags = 0;
16700
16701     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16702                                          "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
16703
16704     VkImage localImage;
16705     vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16706     m_errorMonitor->VerifyFound();
16707
16708     VkFormat unsupported = VK_FORMAT_UNDEFINED;
16709     // Look for a format that is COMPLETELY unsupported with this hardware
16710     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
16711         VkFormat format = static_cast<VkFormat>(f);
16712         VkFormatProperties fProps = m_device->format_properties(format);
16713         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
16714             unsupported = format;
16715             break;
16716         }
16717     }
16718
16719     if (unsupported != VK_FORMAT_UNDEFINED) {
16720         image_create_info.format = unsupported;
16721         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
16722
16723         vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16724         m_errorMonitor->VerifyFound();
16725     }
16726 }
16727
16728 TEST_F(VkLayerTest, ImageLayerViewTests) {
16729     VkResult ret;
16730     TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
16731
16732     ASSERT_NO_FATAL_FAILURE(InitState());
16733
16734     VkImageObj image(m_device);
16735     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16736                VK_IMAGE_TILING_OPTIMAL, 0);
16737     ASSERT_TRUE(image.initialized());
16738
16739     VkImageView imgView;
16740     VkImageViewCreateInfo imgViewInfo = {};
16741     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16742     imgViewInfo.image = image.handle();
16743     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
16744     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16745     imgViewInfo.subresourceRange.layerCount = 1;
16746     imgViewInfo.subresourceRange.baseMipLevel = 0;
16747     imgViewInfo.subresourceRange.levelCount = 1;
16748     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16749
16750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel");
16751     // View can't have baseMipLevel >= image's mipLevels - Expect
16752     // VIEW_CREATE_ERROR
16753     imgViewInfo.subresourceRange.baseMipLevel = 1;
16754     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16755     m_errorMonitor->VerifyFound();
16756     imgViewInfo.subresourceRange.baseMipLevel = 0;
16757
16758     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer");
16759     // View can't have baseArrayLayer >= image's arraySize - Expect
16760     // VIEW_CREATE_ERROR
16761     imgViewInfo.subresourceRange.baseArrayLayer = 1;
16762     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16763     m_errorMonitor->VerifyFound();
16764     imgViewInfo.subresourceRange.baseArrayLayer = 0;
16765
16766     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16767                                                                         "pCreateInfo->subresourceRange."
16768                                                                         "levelCount");
16769     // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR
16770     imgViewInfo.subresourceRange.levelCount = 0;
16771     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16772     m_errorMonitor->VerifyFound();
16773     imgViewInfo.subresourceRange.levelCount = 1;
16774
16775     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16776                                                                         "pCreateInfo->subresourceRange."
16777                                                                         "layerCount");
16778     // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR
16779     imgViewInfo.subresourceRange.layerCount = 0;
16780     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16781     m_errorMonitor->VerifyFound();
16782     imgViewInfo.subresourceRange.layerCount = 1;
16783
16784     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats");
16785     // Can't use depth format for view into color image - Expect INVALID_FORMAT
16786     imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
16787     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16788     m_errorMonitor->VerifyFound();
16789     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16790
16791     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless "
16792                                                                         "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
16793                                                                         "was set on image creation.");
16794     // Same compatibility class but no MUTABLE_FORMAT bit - Expect
16795     // VIEW_CREATE_ERROR
16796     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
16797     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16798     m_errorMonitor->VerifyFound();
16799     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16800
16801     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with "
16802                                                                         "differing formats but they must be "
16803                                                                         "in the same compatibility class.");
16804     // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect
16805     // VIEW_CREATE_ERROR
16806     VkImageCreateInfo mutImgInfo = image.create_info();
16807     VkImage mutImage;
16808     mutImgInfo.format = VK_FORMAT_R8_UINT;
16809     assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
16810     mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
16811     mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
16812     ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage);
16813     ASSERT_VK_SUCCESS(ret);
16814     imgViewInfo.image = mutImage;
16815     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16816     m_errorMonitor->VerifyFound();
16817     imgViewInfo.image = image.handle();
16818     vkDestroyImage(m_device->handle(), mutImage, NULL);
16819 }
16820
16821 TEST_F(VkLayerTest, MiscImageLayerTests) {
16822
16823     TEST_DESCRIPTION("Image layer tests that don't belong elsewhare");
16824
16825     ASSERT_NO_FATAL_FAILURE(InitState());
16826
16827     VkImageObj image(m_device);
16828     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16829                VK_IMAGE_TILING_OPTIMAL, 0);
16830     ASSERT_TRUE(image.initialized());
16831
16832     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero");
16833     vk_testing::Buffer buffer;
16834     VkMemoryPropertyFlags reqs = 0;
16835     buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
16836     VkBufferImageCopy region = {};
16837     region.bufferRowLength = 128;
16838     region.bufferImageHeight = 128;
16839     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16840     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
16841     region.imageSubresource.layerCount = 0;
16842     region.imageExtent.height = 4;
16843     region.imageExtent.width = 4;
16844     region.imageExtent.depth = 1;
16845     m_commandBuffer->BeginCommandBuffer();
16846     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16847                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16848     m_errorMonitor->VerifyFound();
16849     region.imageSubresource.layerCount = 1;
16850
16851     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
16852     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
16853     region.bufferOffset = 6;
16854     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size");
16855     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16856                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16857     m_errorMonitor->VerifyFound();
16858
16859     // BufferOffset must be a multiple of 4
16860     // Introduce failure by setting bufferOffset to a value not divisible by 4
16861     region.bufferOffset = 6;
16862     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4");
16863     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16864                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16865     m_errorMonitor->VerifyFound();
16866
16867     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
16868     region.bufferOffset = 0;
16869     region.imageExtent.height = 128;
16870     region.imageExtent.width = 128;
16871     // Introduce failure by setting bufferRowLength > 0 but less than width
16872     region.bufferRowLength = 64;
16873     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16874                                          "must be zero or greater-than-or-equal-to imageExtent.width");
16875     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16876                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16877     m_errorMonitor->VerifyFound();
16878
16879     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
16880     region.bufferRowLength = 128;
16881     // Introduce failure by setting bufferRowHeight > 0 but less than height
16882     region.bufferImageHeight = 64;
16883     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16884                                          "must be zero or greater-than-or-equal-to imageExtent.height");
16885     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16886                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16887     m_errorMonitor->VerifyFound();
16888
16889     region.bufferImageHeight = 128;
16890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must "
16891                                                                         "specify only COLOR or DEPTH or "
16892                                                                         "STENCIL");
16893     // Expect MISMATCHED_IMAGE_ASPECT
16894     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16895     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16896                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16897     m_errorMonitor->VerifyFound();
16898     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16899
16900     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16901                                          "If the format of srcImage is a depth, stencil, depth stencil or "
16902                                          "integer-based format then filter must be VK_FILTER_NEAREST");
16903     // Expect INVALID_FILTER
16904     VkImageObj intImage1(m_device);
16905     intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16906     VkImageObj intImage2(m_device);
16907     intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16908     VkImageBlit blitRegion = {};
16909     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16910     blitRegion.srcSubresource.baseArrayLayer = 0;
16911     blitRegion.srcSubresource.layerCount = 1;
16912     blitRegion.srcSubresource.mipLevel = 0;
16913     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16914     blitRegion.dstSubresource.baseArrayLayer = 0;
16915     blitRegion.dstSubresource.layerCount = 1;
16916     blitRegion.dstSubresource.mipLevel = 0;
16917
16918     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16919                    intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR);
16920     m_errorMonitor->VerifyFound();
16921
16922     // Look for NULL-blit warning
16923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area.");
16924     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16925                    intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR);
16926     m_errorMonitor->VerifyFound();
16927
16928     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers");
16929     VkImageMemoryBarrier img_barrier;
16930     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
16931     img_barrier.pNext = NULL;
16932     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
16933     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
16934     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16935     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16936     img_barrier.image = image.handle();
16937     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16938     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16939     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16940     img_barrier.subresourceRange.baseArrayLayer = 0;
16941     img_barrier.subresourceRange.baseMipLevel = 0;
16942     // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE
16943     img_barrier.subresourceRange.layerCount = 0;
16944     img_barrier.subresourceRange.levelCount = 1;
16945     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
16946                          nullptr, 0, nullptr, 1, &img_barrier);
16947     m_errorMonitor->VerifyFound();
16948     img_barrier.subresourceRange.layerCount = 1;
16949 }
16950
16951 TEST_F(VkLayerTest, ImageFormatLimits) {
16952
16953     TEST_DESCRIPTION("Exceed the limits of image format ");
16954
16955     ASSERT_NO_FATAL_FAILURE(InitState());
16956     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16957     VkImageCreateInfo image_create_info = {};
16958     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16959     image_create_info.pNext = NULL;
16960     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16961     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16962     image_create_info.extent.width = 32;
16963     image_create_info.extent.height = 32;
16964     image_create_info.extent.depth = 1;
16965     image_create_info.mipLevels = 1;
16966     image_create_info.arrayLayers = 1;
16967     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16968     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16969     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16970     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
16971     image_create_info.flags = 0;
16972
16973     VkImage nullImg;
16974     VkImageFormatProperties imgFmtProps;
16975     vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
16976                                              image_create_info.usage, image_create_info.flags, &imgFmtProps);
16977     image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1;
16978     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16979     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16980     m_errorMonitor->VerifyFound();
16981     image_create_info.extent.depth = 1;
16982
16983     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16984     image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
16985     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16986     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16987     m_errorMonitor->VerifyFound();
16988     image_create_info.mipLevels = 1;
16989
16990     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16991     image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
16992     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16993     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16994     m_errorMonitor->VerifyFound();
16995     image_create_info.arrayLayers = 1;
16996
16997     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format");
16998     int samples = imgFmtProps.sampleCounts >> 1;
16999     image_create_info.samples = (VkSampleCountFlagBits)samples;
17000     // Expect INVALID_FORMAT_LIMITS_VIOLATION
17001     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17002     m_errorMonitor->VerifyFound();
17003     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17004
17005     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be "
17006                                                                         "VK_IMAGE_LAYOUT_UNDEFINED or "
17007                                                                         "VK_IMAGE_LAYOUT_PREINITIALIZED");
17008     image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
17009     // Expect INVALID_LAYOUT
17010     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17011     m_errorMonitor->VerifyFound();
17012     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17013 }
17014
17015 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
17016     VkResult err;
17017     bool pass;
17018
17019     // Create color images with different format sizes and try to copy between them
17020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17021                                          "vkCmdCopyImage called with unmatched source and dest image format sizes");
17022
17023     ASSERT_NO_FATAL_FAILURE(InitState());
17024
17025     // Create two images of different types and try to copy between them
17026     VkImage srcImage;
17027     VkImage dstImage;
17028     VkDeviceMemory srcMem;
17029     VkDeviceMemory destMem;
17030     VkMemoryRequirements memReqs;
17031
17032     VkImageCreateInfo image_create_info = {};
17033     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17034     image_create_info.pNext = NULL;
17035     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17036     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17037     image_create_info.extent.width = 32;
17038     image_create_info.extent.height = 32;
17039     image_create_info.extent.depth = 1;
17040     image_create_info.mipLevels = 1;
17041     image_create_info.arrayLayers = 1;
17042     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17043     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17044     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17045     image_create_info.flags = 0;
17046
17047     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17048     ASSERT_VK_SUCCESS(err);
17049
17050     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17051     // Introduce failure by creating second image with a different-sized format.
17052     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
17053
17054     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17055     ASSERT_VK_SUCCESS(err);
17056
17057     // Allocate memory
17058     VkMemoryAllocateInfo memAlloc = {};
17059     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17060     memAlloc.pNext = NULL;
17061     memAlloc.allocationSize = 0;
17062     memAlloc.memoryTypeIndex = 0;
17063
17064     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17065     memAlloc.allocationSize = memReqs.size;
17066     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17067     ASSERT_TRUE(pass);
17068     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17069     ASSERT_VK_SUCCESS(err);
17070
17071     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17072     memAlloc.allocationSize = memReqs.size;
17073     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17074     ASSERT_TRUE(pass);
17075     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17076     ASSERT_VK_SUCCESS(err);
17077
17078     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17079     ASSERT_VK_SUCCESS(err);
17080     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17081     ASSERT_VK_SUCCESS(err);
17082
17083     BeginCommandBuffer();
17084     VkImageCopy copyRegion;
17085     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17086     copyRegion.srcSubresource.mipLevel = 0;
17087     copyRegion.srcSubresource.baseArrayLayer = 0;
17088     copyRegion.srcSubresource.layerCount = 0;
17089     copyRegion.srcOffset.x = 0;
17090     copyRegion.srcOffset.y = 0;
17091     copyRegion.srcOffset.z = 0;
17092     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17093     copyRegion.dstSubresource.mipLevel = 0;
17094     copyRegion.dstSubresource.baseArrayLayer = 0;
17095     copyRegion.dstSubresource.layerCount = 0;
17096     copyRegion.dstOffset.x = 0;
17097     copyRegion.dstOffset.y = 0;
17098     copyRegion.dstOffset.z = 0;
17099     copyRegion.extent.width = 1;
17100     copyRegion.extent.height = 1;
17101     copyRegion.extent.depth = 1;
17102     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17103     EndCommandBuffer();
17104
17105     m_errorMonitor->VerifyFound();
17106
17107     vkDestroyImage(m_device->device(), srcImage, NULL);
17108     vkDestroyImage(m_device->device(), dstImage, NULL);
17109     vkFreeMemory(m_device->device(), srcMem, NULL);
17110     vkFreeMemory(m_device->device(), destMem, NULL);
17111 }
17112
17113 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
17114     VkResult err;
17115     bool pass;
17116
17117     // Create a color image and a depth/stencil image and try to copy between them
17118     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17119                                          "vkCmdCopyImage called with unmatched source and dest image depth");
17120
17121     ASSERT_NO_FATAL_FAILURE(InitState());
17122
17123     // Create two images of different types and try to copy between them
17124     VkImage srcImage;
17125     VkImage dstImage;
17126     VkDeviceMemory srcMem;
17127     VkDeviceMemory destMem;
17128     VkMemoryRequirements memReqs;
17129
17130     VkImageCreateInfo image_create_info = {};
17131     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17132     image_create_info.pNext = NULL;
17133     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17134     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17135     image_create_info.extent.width = 32;
17136     image_create_info.extent.height = 32;
17137     image_create_info.extent.depth = 1;
17138     image_create_info.mipLevels = 1;
17139     image_create_info.arrayLayers = 1;
17140     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17141     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17142     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17143     image_create_info.flags = 0;
17144
17145     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17146     ASSERT_VK_SUCCESS(err);
17147
17148     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17149
17150     // Introduce failure by creating second image with a depth/stencil format
17151     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17152     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17153     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17154
17155     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17156     ASSERT_VK_SUCCESS(err);
17157
17158     // Allocate memory
17159     VkMemoryAllocateInfo memAlloc = {};
17160     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17161     memAlloc.pNext = NULL;
17162     memAlloc.allocationSize = 0;
17163     memAlloc.memoryTypeIndex = 0;
17164
17165     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17166     memAlloc.allocationSize = memReqs.size;
17167     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17168     ASSERT_TRUE(pass);
17169     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17170     ASSERT_VK_SUCCESS(err);
17171
17172     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17173     memAlloc.allocationSize = memReqs.size;
17174     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17175     ASSERT_TRUE(pass);
17176     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17177     ASSERT_VK_SUCCESS(err);
17178
17179     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17180     ASSERT_VK_SUCCESS(err);
17181     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17182     ASSERT_VK_SUCCESS(err);
17183
17184     BeginCommandBuffer();
17185     VkImageCopy copyRegion;
17186     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17187     copyRegion.srcSubresource.mipLevel = 0;
17188     copyRegion.srcSubresource.baseArrayLayer = 0;
17189     copyRegion.srcSubresource.layerCount = 0;
17190     copyRegion.srcOffset.x = 0;
17191     copyRegion.srcOffset.y = 0;
17192     copyRegion.srcOffset.z = 0;
17193     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17194     copyRegion.dstSubresource.mipLevel = 0;
17195     copyRegion.dstSubresource.baseArrayLayer = 0;
17196     copyRegion.dstSubresource.layerCount = 0;
17197     copyRegion.dstOffset.x = 0;
17198     copyRegion.dstOffset.y = 0;
17199     copyRegion.dstOffset.z = 0;
17200     copyRegion.extent.width = 1;
17201     copyRegion.extent.height = 1;
17202     copyRegion.extent.depth = 1;
17203     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17204     EndCommandBuffer();
17205
17206     m_errorMonitor->VerifyFound();
17207
17208     vkDestroyImage(m_device->device(), srcImage, NULL);
17209     vkDestroyImage(m_device->device(), dstImage, NULL);
17210     vkFreeMemory(m_device->device(), srcMem, NULL);
17211     vkFreeMemory(m_device->device(), destMem, NULL);
17212 }
17213
17214 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
17215     VkResult err;
17216     bool pass;
17217
17218     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17219                                          "vkCmdResolveImage called with source sample count less than 2.");
17220
17221     ASSERT_NO_FATAL_FAILURE(InitState());
17222
17223     // Create two images of sample count 1 and try to Resolve between them
17224     VkImage srcImage;
17225     VkImage dstImage;
17226     VkDeviceMemory srcMem;
17227     VkDeviceMemory destMem;
17228     VkMemoryRequirements memReqs;
17229
17230     VkImageCreateInfo image_create_info = {};
17231     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17232     image_create_info.pNext = NULL;
17233     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17234     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17235     image_create_info.extent.width = 32;
17236     image_create_info.extent.height = 1;
17237     image_create_info.extent.depth = 1;
17238     image_create_info.mipLevels = 1;
17239     image_create_info.arrayLayers = 1;
17240     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17241     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17242     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17243     image_create_info.flags = 0;
17244
17245     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17246     ASSERT_VK_SUCCESS(err);
17247
17248     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17249
17250     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17251     ASSERT_VK_SUCCESS(err);
17252
17253     // Allocate memory
17254     VkMemoryAllocateInfo memAlloc = {};
17255     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17256     memAlloc.pNext = NULL;
17257     memAlloc.allocationSize = 0;
17258     memAlloc.memoryTypeIndex = 0;
17259
17260     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17261     memAlloc.allocationSize = memReqs.size;
17262     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17263     ASSERT_TRUE(pass);
17264     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17265     ASSERT_VK_SUCCESS(err);
17266
17267     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17268     memAlloc.allocationSize = memReqs.size;
17269     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17270     ASSERT_TRUE(pass);
17271     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17272     ASSERT_VK_SUCCESS(err);
17273
17274     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17275     ASSERT_VK_SUCCESS(err);
17276     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17277     ASSERT_VK_SUCCESS(err);
17278
17279     BeginCommandBuffer();
17280     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17281     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17282     // VK_IMAGE_LAYOUT_GENERAL = 1,
17283     VkImageResolve resolveRegion;
17284     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17285     resolveRegion.srcSubresource.mipLevel = 0;
17286     resolveRegion.srcSubresource.baseArrayLayer = 0;
17287     resolveRegion.srcSubresource.layerCount = 1;
17288     resolveRegion.srcOffset.x = 0;
17289     resolveRegion.srcOffset.y = 0;
17290     resolveRegion.srcOffset.z = 0;
17291     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17292     resolveRegion.dstSubresource.mipLevel = 0;
17293     resolveRegion.dstSubresource.baseArrayLayer = 0;
17294     resolveRegion.dstSubresource.layerCount = 1;
17295     resolveRegion.dstOffset.x = 0;
17296     resolveRegion.dstOffset.y = 0;
17297     resolveRegion.dstOffset.z = 0;
17298     resolveRegion.extent.width = 1;
17299     resolveRegion.extent.height = 1;
17300     resolveRegion.extent.depth = 1;
17301     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17302     EndCommandBuffer();
17303
17304     m_errorMonitor->VerifyFound();
17305
17306     vkDestroyImage(m_device->device(), srcImage, NULL);
17307     vkDestroyImage(m_device->device(), dstImage, NULL);
17308     vkFreeMemory(m_device->device(), srcMem, NULL);
17309     vkFreeMemory(m_device->device(), destMem, NULL);
17310 }
17311
17312 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
17313     VkResult err;
17314     bool pass;
17315
17316     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17317                                          "vkCmdResolveImage called with dest sample count greater than 1.");
17318
17319     ASSERT_NO_FATAL_FAILURE(InitState());
17320
17321     // Create two images of sample count 4 and try to Resolve between them
17322     VkImage srcImage;
17323     VkImage dstImage;
17324     VkDeviceMemory srcMem;
17325     VkDeviceMemory destMem;
17326     VkMemoryRequirements memReqs;
17327
17328     VkImageCreateInfo image_create_info = {};
17329     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17330     image_create_info.pNext = NULL;
17331     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17332     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17333     image_create_info.extent.width = 32;
17334     image_create_info.extent.height = 1;
17335     image_create_info.extent.depth = 1;
17336     image_create_info.mipLevels = 1;
17337     image_create_info.arrayLayers = 1;
17338     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
17339     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17340     // Note: Some implementations expect color attachment usage for any
17341     // multisample surface
17342     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17343     image_create_info.flags = 0;
17344
17345     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17346     ASSERT_VK_SUCCESS(err);
17347
17348     // Note: Some implementations expect color attachment usage for any
17349     // multisample surface
17350     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17351
17352     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17353     ASSERT_VK_SUCCESS(err);
17354
17355     // Allocate memory
17356     VkMemoryAllocateInfo memAlloc = {};
17357     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17358     memAlloc.pNext = NULL;
17359     memAlloc.allocationSize = 0;
17360     memAlloc.memoryTypeIndex = 0;
17361
17362     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17363     memAlloc.allocationSize = memReqs.size;
17364     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17365     ASSERT_TRUE(pass);
17366     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17367     ASSERT_VK_SUCCESS(err);
17368
17369     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17370     memAlloc.allocationSize = memReqs.size;
17371     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17372     ASSERT_TRUE(pass);
17373     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17374     ASSERT_VK_SUCCESS(err);
17375
17376     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17377     ASSERT_VK_SUCCESS(err);
17378     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17379     ASSERT_VK_SUCCESS(err);
17380
17381     BeginCommandBuffer();
17382     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17383     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17384     // VK_IMAGE_LAYOUT_GENERAL = 1,
17385     VkImageResolve resolveRegion;
17386     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17387     resolveRegion.srcSubresource.mipLevel = 0;
17388     resolveRegion.srcSubresource.baseArrayLayer = 0;
17389     resolveRegion.srcSubresource.layerCount = 1;
17390     resolveRegion.srcOffset.x = 0;
17391     resolveRegion.srcOffset.y = 0;
17392     resolveRegion.srcOffset.z = 0;
17393     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17394     resolveRegion.dstSubresource.mipLevel = 0;
17395     resolveRegion.dstSubresource.baseArrayLayer = 0;
17396     resolveRegion.dstSubresource.layerCount = 1;
17397     resolveRegion.dstOffset.x = 0;
17398     resolveRegion.dstOffset.y = 0;
17399     resolveRegion.dstOffset.z = 0;
17400     resolveRegion.extent.width = 1;
17401     resolveRegion.extent.height = 1;
17402     resolveRegion.extent.depth = 1;
17403     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17404     EndCommandBuffer();
17405
17406     m_errorMonitor->VerifyFound();
17407
17408     vkDestroyImage(m_device->device(), srcImage, NULL);
17409     vkDestroyImage(m_device->device(), dstImage, NULL);
17410     vkFreeMemory(m_device->device(), srcMem, NULL);
17411     vkFreeMemory(m_device->device(), destMem, NULL);
17412 }
17413
17414 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
17415     VkResult err;
17416     bool pass;
17417
17418     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17419                                          "vkCmdResolveImage called with unmatched source and dest formats.");
17420
17421     ASSERT_NO_FATAL_FAILURE(InitState());
17422
17423     // Create two images of different types and try to copy between them
17424     VkImage srcImage;
17425     VkImage dstImage;
17426     VkDeviceMemory srcMem;
17427     VkDeviceMemory destMem;
17428     VkMemoryRequirements memReqs;
17429
17430     VkImageCreateInfo image_create_info = {};
17431     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17432     image_create_info.pNext = NULL;
17433     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17434     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17435     image_create_info.extent.width = 32;
17436     image_create_info.extent.height = 1;
17437     image_create_info.extent.depth = 1;
17438     image_create_info.mipLevels = 1;
17439     image_create_info.arrayLayers = 1;
17440     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17441     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17442     // Note: Some implementations expect color attachment usage for any
17443     // multisample surface
17444     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17445     image_create_info.flags = 0;
17446
17447     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17448     ASSERT_VK_SUCCESS(err);
17449
17450     // Set format to something other than source image
17451     image_create_info.format = VK_FORMAT_R32_SFLOAT;
17452     // Note: Some implementations expect color attachment usage for any
17453     // multisample surface
17454     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17455     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17456
17457     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17458     ASSERT_VK_SUCCESS(err);
17459
17460     // Allocate memory
17461     VkMemoryAllocateInfo memAlloc = {};
17462     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17463     memAlloc.pNext = NULL;
17464     memAlloc.allocationSize = 0;
17465     memAlloc.memoryTypeIndex = 0;
17466
17467     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17468     memAlloc.allocationSize = memReqs.size;
17469     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17470     ASSERT_TRUE(pass);
17471     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17472     ASSERT_VK_SUCCESS(err);
17473
17474     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17475     memAlloc.allocationSize = memReqs.size;
17476     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17477     ASSERT_TRUE(pass);
17478     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17479     ASSERT_VK_SUCCESS(err);
17480
17481     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17482     ASSERT_VK_SUCCESS(err);
17483     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17484     ASSERT_VK_SUCCESS(err);
17485
17486     BeginCommandBuffer();
17487     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17488     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17489     // VK_IMAGE_LAYOUT_GENERAL = 1,
17490     VkImageResolve resolveRegion;
17491     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17492     resolveRegion.srcSubresource.mipLevel = 0;
17493     resolveRegion.srcSubresource.baseArrayLayer = 0;
17494     resolveRegion.srcSubresource.layerCount = 1;
17495     resolveRegion.srcOffset.x = 0;
17496     resolveRegion.srcOffset.y = 0;
17497     resolveRegion.srcOffset.z = 0;
17498     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17499     resolveRegion.dstSubresource.mipLevel = 0;
17500     resolveRegion.dstSubresource.baseArrayLayer = 0;
17501     resolveRegion.dstSubresource.layerCount = 1;
17502     resolveRegion.dstOffset.x = 0;
17503     resolveRegion.dstOffset.y = 0;
17504     resolveRegion.dstOffset.z = 0;
17505     resolveRegion.extent.width = 1;
17506     resolveRegion.extent.height = 1;
17507     resolveRegion.extent.depth = 1;
17508     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17509     EndCommandBuffer();
17510
17511     m_errorMonitor->VerifyFound();
17512
17513     vkDestroyImage(m_device->device(), srcImage, NULL);
17514     vkDestroyImage(m_device->device(), dstImage, NULL);
17515     vkFreeMemory(m_device->device(), srcMem, NULL);
17516     vkFreeMemory(m_device->device(), destMem, NULL);
17517 }
17518
17519 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
17520     VkResult err;
17521     bool pass;
17522
17523     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17524                                          "vkCmdResolveImage called with unmatched source and dest image types.");
17525
17526     ASSERT_NO_FATAL_FAILURE(InitState());
17527
17528     // Create two images of different types and try to copy between them
17529     VkImage srcImage;
17530     VkImage dstImage;
17531     VkDeviceMemory srcMem;
17532     VkDeviceMemory destMem;
17533     VkMemoryRequirements memReqs;
17534
17535     VkImageCreateInfo image_create_info = {};
17536     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17537     image_create_info.pNext = NULL;
17538     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17539     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17540     image_create_info.extent.width = 32;
17541     image_create_info.extent.height = 1;
17542     image_create_info.extent.depth = 1;
17543     image_create_info.mipLevels = 1;
17544     image_create_info.arrayLayers = 1;
17545     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17546     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17547     // Note: Some implementations expect color attachment usage for any
17548     // multisample surface
17549     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17550     image_create_info.flags = 0;
17551
17552     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17553     ASSERT_VK_SUCCESS(err);
17554
17555     image_create_info.imageType = VK_IMAGE_TYPE_1D;
17556     // Note: Some implementations expect color attachment usage for any
17557     // multisample surface
17558     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17559     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17560
17561     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17562     ASSERT_VK_SUCCESS(err);
17563
17564     // Allocate memory
17565     VkMemoryAllocateInfo memAlloc = {};
17566     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17567     memAlloc.pNext = NULL;
17568     memAlloc.allocationSize = 0;
17569     memAlloc.memoryTypeIndex = 0;
17570
17571     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17572     memAlloc.allocationSize = memReqs.size;
17573     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17574     ASSERT_TRUE(pass);
17575     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17576     ASSERT_VK_SUCCESS(err);
17577
17578     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17579     memAlloc.allocationSize = memReqs.size;
17580     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17581     ASSERT_TRUE(pass);
17582     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17583     ASSERT_VK_SUCCESS(err);
17584
17585     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17586     ASSERT_VK_SUCCESS(err);
17587     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17588     ASSERT_VK_SUCCESS(err);
17589
17590     BeginCommandBuffer();
17591     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17592     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17593     // VK_IMAGE_LAYOUT_GENERAL = 1,
17594     VkImageResolve resolveRegion;
17595     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17596     resolveRegion.srcSubresource.mipLevel = 0;
17597     resolveRegion.srcSubresource.baseArrayLayer = 0;
17598     resolveRegion.srcSubresource.layerCount = 1;
17599     resolveRegion.srcOffset.x = 0;
17600     resolveRegion.srcOffset.y = 0;
17601     resolveRegion.srcOffset.z = 0;
17602     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17603     resolveRegion.dstSubresource.mipLevel = 0;
17604     resolveRegion.dstSubresource.baseArrayLayer = 0;
17605     resolveRegion.dstSubresource.layerCount = 1;
17606     resolveRegion.dstOffset.x = 0;
17607     resolveRegion.dstOffset.y = 0;
17608     resolveRegion.dstOffset.z = 0;
17609     resolveRegion.extent.width = 1;
17610     resolveRegion.extent.height = 1;
17611     resolveRegion.extent.depth = 1;
17612     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17613     EndCommandBuffer();
17614
17615     m_errorMonitor->VerifyFound();
17616
17617     vkDestroyImage(m_device->device(), srcImage, NULL);
17618     vkDestroyImage(m_device->device(), dstImage, NULL);
17619     vkFreeMemory(m_device->device(), srcMem, NULL);
17620     vkFreeMemory(m_device->device(), destMem, NULL);
17621 }
17622
17623 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
17624     // Create a single Image descriptor and cause it to first hit an error due
17625     //  to using a DS format, then cause it to hit error due to COLOR_BIT not
17626     //  set in aspect
17627     // The image format check comes 2nd in validation so we trigger it first,
17628     //  then when we cause aspect fail next, bad format check will be preempted
17629     VkResult err;
17630
17631     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17632                                          "Combination depth/stencil image formats can have only the ");
17633
17634     ASSERT_NO_FATAL_FAILURE(InitState());
17635
17636     VkDescriptorPoolSize ds_type_count = {};
17637     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17638     ds_type_count.descriptorCount = 1;
17639
17640     VkDescriptorPoolCreateInfo ds_pool_ci = {};
17641     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
17642     ds_pool_ci.pNext = NULL;
17643     ds_pool_ci.maxSets = 1;
17644     ds_pool_ci.poolSizeCount = 1;
17645     ds_pool_ci.pPoolSizes = &ds_type_count;
17646
17647     VkDescriptorPool ds_pool;
17648     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
17649     ASSERT_VK_SUCCESS(err);
17650
17651     VkDescriptorSetLayoutBinding dsl_binding = {};
17652     dsl_binding.binding = 0;
17653     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17654     dsl_binding.descriptorCount = 1;
17655     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
17656     dsl_binding.pImmutableSamplers = NULL;
17657
17658     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
17659     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
17660     ds_layout_ci.pNext = NULL;
17661     ds_layout_ci.bindingCount = 1;
17662     ds_layout_ci.pBindings = &dsl_binding;
17663     VkDescriptorSetLayout ds_layout;
17664     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
17665     ASSERT_VK_SUCCESS(err);
17666
17667     VkDescriptorSet descriptorSet;
17668     VkDescriptorSetAllocateInfo alloc_info = {};
17669     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
17670     alloc_info.descriptorSetCount = 1;
17671     alloc_info.descriptorPool = ds_pool;
17672     alloc_info.pSetLayouts = &ds_layout;
17673     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
17674     ASSERT_VK_SUCCESS(err);
17675
17676     VkImage image_bad;
17677     VkImage image_good;
17678     // One bad format and one good format for Color attachment
17679     const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
17680     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
17681     const int32_t tex_width = 32;
17682     const int32_t tex_height = 32;
17683
17684     VkImageCreateInfo image_create_info = {};
17685     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17686     image_create_info.pNext = NULL;
17687     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17688     image_create_info.format = tex_format_bad;
17689     image_create_info.extent.width = tex_width;
17690     image_create_info.extent.height = tex_height;
17691     image_create_info.extent.depth = 1;
17692     image_create_info.mipLevels = 1;
17693     image_create_info.arrayLayers = 1;
17694     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17695     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17696     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17697     image_create_info.flags = 0;
17698
17699     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
17700     ASSERT_VK_SUCCESS(err);
17701     image_create_info.format = tex_format_good;
17702     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17703     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
17704     ASSERT_VK_SUCCESS(err);
17705
17706     VkImageViewCreateInfo image_view_create_info = {};
17707     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17708     image_view_create_info.image = image_bad;
17709     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
17710     image_view_create_info.format = tex_format_bad;
17711     image_view_create_info.subresourceRange.baseArrayLayer = 0;
17712     image_view_create_info.subresourceRange.baseMipLevel = 0;
17713     image_view_create_info.subresourceRange.layerCount = 1;
17714     image_view_create_info.subresourceRange.levelCount = 1;
17715     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17716
17717     VkImageView view;
17718     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
17719
17720     m_errorMonitor->VerifyFound();
17721
17722     vkDestroyImage(m_device->device(), image_bad, NULL);
17723     vkDestroyImage(m_device->device(), image_good, NULL);
17724     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
17725     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
17726 }
17727
17728 TEST_F(VkLayerTest, ClearImageErrors) {
17729     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and "
17730                      "ClearDepthStencilImage with a color image.");
17731
17732     ASSERT_NO_FATAL_FAILURE(InitState());
17733     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17734
17735     // Renderpass is started here so end it as Clear cmds can't be in renderpass
17736     BeginCommandBuffer();
17737     m_commandBuffer->EndRenderPass();
17738
17739     // Color image
17740     VkClearColorValue clear_color;
17741     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
17742     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
17743     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
17744     const int32_t img_width = 32;
17745     const int32_t img_height = 32;
17746     VkImageCreateInfo image_create_info = {};
17747     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17748     image_create_info.pNext = NULL;
17749     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17750     image_create_info.format = color_format;
17751     image_create_info.extent.width = img_width;
17752     image_create_info.extent.height = img_height;
17753     image_create_info.extent.depth = 1;
17754     image_create_info.mipLevels = 1;
17755     image_create_info.arrayLayers = 1;
17756     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17757     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17758     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
17759
17760     vk_testing::Image color_image;
17761     color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
17762
17763     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
17764
17765     // Depth/Stencil image
17766     VkClearDepthStencilValue clear_value = {0};
17767     reqs = 0; // don't need HOST_VISIBLE DS image
17768     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
17769     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
17770     ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17771     ds_image_create_info.extent.width = 64;
17772     ds_image_create_info.extent.height = 64;
17773     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17774     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17775
17776     vk_testing::Image ds_image;
17777     ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs);
17778
17779     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
17780
17781     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
17782
17783     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17784                          &color_range);
17785
17786     m_errorMonitor->VerifyFound();
17787
17788     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with "
17789                                                                         "image created without "
17790                                                                         "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
17791
17792     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17793                          &color_range);
17794
17795     m_errorMonitor->VerifyFound();
17796
17797     // Call CmdClearDepthStencilImage with color image
17798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17799                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
17800
17801     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(),
17802                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range);
17803
17804     m_errorMonitor->VerifyFound();
17805 }
17806 #endif // IMAGE_TESTS
17807
17808 #if defined(ANDROID) && defined(VALIDATION_APK)
17809 static bool initialized = false;
17810 static bool active = false;
17811
17812 // Convert Intents to argv
17813 // Ported from Hologram sample, only difference is flexible key
17814 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
17815     std::vector<std::string> args;
17816     JavaVM &vm = *app.activity->vm;
17817     JNIEnv *p_env;
17818     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
17819         return args;
17820
17821     JNIEnv &env = *p_env;
17822     jobject activity = app.activity->clazz;
17823     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
17824     jobject intent = env.CallObjectMethod(activity, get_intent_method);
17825     jmethodID get_string_extra_method =
17826         env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
17827     jvalue get_string_extra_args;
17828     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
17829     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
17830
17831     std::string args_str;
17832     if (extra_str) {
17833         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
17834         args_str = extra_utf;
17835         env.ReleaseStringUTFChars(extra_str, extra_utf);
17836         env.DeleteLocalRef(extra_str);
17837     }
17838
17839     env.DeleteLocalRef(get_string_extra_args.l);
17840     env.DeleteLocalRef(intent);
17841     vm.DetachCurrentThread();
17842
17843     // split args_str
17844     std::stringstream ss(args_str);
17845     std::string arg;
17846     while (std::getline(ss, arg, ' ')) {
17847         if (!arg.empty())
17848             args.push_back(arg);
17849     }
17850
17851     return args;
17852 }
17853
17854 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
17855
17856 static void processCommand(struct android_app *app, int32_t cmd) {
17857     switch (cmd) {
17858     case APP_CMD_INIT_WINDOW: {
17859         if (app->window) {
17860             initialized = true;
17861         }
17862         break;
17863     }
17864     case APP_CMD_GAINED_FOCUS: {
17865         active = true;
17866         break;
17867     }
17868     case APP_CMD_LOST_FOCUS: {
17869         active = false;
17870         break;
17871     }
17872     }
17873 }
17874
17875 void android_main(struct android_app *app) {
17876     app_dummy();
17877
17878     const char *appTag = "VulkanLayerValidationTests";
17879
17880     int vulkanSupport = InitVulkan();
17881     if (vulkanSupport == 0) {
17882         __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
17883         return;
17884     }
17885
17886     app->onAppCmd = processCommand;
17887     app->onInputEvent = processInput;
17888
17889     while (1) {
17890         int events;
17891         struct android_poll_source *source;
17892         while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
17893             if (source) {
17894                 source->process(app, source);
17895             }
17896
17897             if (app->destroyRequested != 0) {
17898                 VkTestFramework::Finish();
17899                 return;
17900             }
17901         }
17902
17903         if (initialized && active) {
17904             // Use the following key to send arguments to gtest, i.e.
17905             // --es args "--gtest_filter=-VkLayerTest.foo"
17906             const char key[] = "args";
17907             std::vector<std::string> args = get_args(*app, key);
17908
17909             std::string filter = "";
17910             if (args.size() > 0) {
17911                 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
17912                 filter += args[0];
17913             } else {
17914                 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
17915             }
17916
17917             int argc = 2;
17918             char *argv[] = {(char *)"foo", (char *)filter.c_str()};
17919             __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
17920
17921             // Route output to files until we can override the gtest output
17922             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
17923             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
17924
17925             ::testing::InitGoogleTest(&argc, argv);
17926             VkTestFramework::InitArgs(&argc, argv);
17927             ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17928
17929             int result = RUN_ALL_TESTS();
17930
17931             if (result != 0) {
17932                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
17933             } else {
17934                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
17935             }
17936
17937             VkTestFramework::Finish();
17938
17939             fclose(stdout);
17940             fclose(stderr);
17941
17942             ANativeActivity_finish(app->activity);
17943
17944             return;
17945         }
17946     }
17947 }
17948 #endif
17949
17950 int main(int argc, char **argv) {
17951     int result;
17952
17953 #ifdef ANDROID
17954     int vulkanSupport = InitVulkan();
17955     if (vulkanSupport == 0)
17956         return 1;
17957 #endif
17958
17959     ::testing::InitGoogleTest(&argc, argv);
17960     VkTestFramework::InitArgs(&argc, argv);
17961
17962     ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17963
17964     result = RUN_ALL_TESTS();
17965
17966     VkTestFramework::Finish();
17967     return result;
17968 }