e37bc02d25ae56213873c6403dfae6f8b8396399
[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     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2468                                          "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
2469     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2470     pass = (err != VK_SUCCESS);
2471     ASSERT_TRUE(pass);
2472     m_errorMonitor->VerifyFound();
2473
2474     // Get the surface capabilities:
2475     VkSurfaceCapabilitiesKHR surface_capabilities;
2476
2477     // Do so correctly (only error logged by this entrypoint is if the
2478     // extension isn't enabled):
2479     err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
2480     pass = (err == VK_SUCCESS);
2481     ASSERT_TRUE(pass);
2482
2483     // Get the surface formats:
2484     uint32_t surface_format_count;
2485
2486     // First, try without a pointer to surface_format_count:
2487     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
2488                                                                         "specified as NULL");
2489     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
2490     pass = (err == VK_SUCCESS);
2491     ASSERT_TRUE(pass);
2492     m_errorMonitor->VerifyFound();
2493
2494     // Next, call with a non-NULL pSurfaceFormats, even though we haven't
2495     // correctly done a 1st try (to get the count):
2496     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2497     surface_format_count = 0;
2498     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
2499     pass = (err == VK_SUCCESS);
2500     ASSERT_TRUE(pass);
2501     m_errorMonitor->VerifyFound();
2502
2503     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2504     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2505     pass = (err == VK_SUCCESS);
2506     ASSERT_TRUE(pass);
2507
2508     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2509     VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
2510
2511     // Next, do a 2nd try with surface_format_count being set too high:
2512     surface_format_count += 5;
2513     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2514     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2515     pass = (err == VK_SUCCESS);
2516     ASSERT_TRUE(pass);
2517     m_errorMonitor->VerifyFound();
2518
2519     // Finally, do a correct 1st and 2nd try:
2520     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2521     pass = (err == VK_SUCCESS);
2522     ASSERT_TRUE(pass);
2523     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2524     pass = (err == VK_SUCCESS);
2525     ASSERT_TRUE(pass);
2526
2527     // Get the surface present modes:
2528     uint32_t surface_present_mode_count;
2529
2530     // First, try without a pointer to surface_format_count:
2531     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
2532                                                                         "specified as NULL");
2533
2534     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
2535     pass = (err == VK_SUCCESS);
2536     ASSERT_TRUE(pass);
2537     m_errorMonitor->VerifyFound();
2538
2539     // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
2540     // correctly done a 1st try (to get the count):
2541     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2542     surface_present_mode_count = 0;
2543     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
2544                                               (VkPresentModeKHR *)&surface_present_mode_count);
2545     pass = (err == VK_SUCCESS);
2546     ASSERT_TRUE(pass);
2547     m_errorMonitor->VerifyFound();
2548
2549     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2550     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2551     pass = (err == VK_SUCCESS);
2552     ASSERT_TRUE(pass);
2553
2554     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2555     VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
2556
2557     // Next, do a 2nd try with surface_format_count being set too high:
2558     surface_present_mode_count += 5;
2559     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2560     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2561     pass = (err == VK_SUCCESS);
2562     ASSERT_TRUE(pass);
2563     m_errorMonitor->VerifyFound();
2564
2565     // Finally, do a correct 1st and 2nd try:
2566     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2567     pass = (err == VK_SUCCESS);
2568     ASSERT_TRUE(pass);
2569     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2570     pass = (err == VK_SUCCESS);
2571     ASSERT_TRUE(pass);
2572
2573     // Create a swapchain:
2574
2575     // First, try without a pointer to swapchain_create_info:
2576     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
2577                                                                         "specified as NULL");
2578
2579     err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
2580     pass = (err != VK_SUCCESS);
2581     ASSERT_TRUE(pass);
2582     m_errorMonitor->VerifyFound();
2583
2584     // Next, call with a non-NULL swapchain_create_info, that has the wrong
2585     // sType:
2586     swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2587     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2588
2589     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2590     pass = (err != VK_SUCCESS);
2591     ASSERT_TRUE(pass);
2592     m_errorMonitor->VerifyFound();
2593
2594     // Next, call with a NULL swapchain pointer:
2595     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2596     swapchain_create_info.pNext = NULL;
2597     swapchain_create_info.flags = 0;
2598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
2599                                                                         "specified as NULL");
2600
2601     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
2602     pass = (err != VK_SUCCESS);
2603     ASSERT_TRUE(pass);
2604     m_errorMonitor->VerifyFound();
2605
2606     // TODO: Enhance swapchain layer so that
2607     // swapchain_create_info.queueFamilyIndexCount is checked against something?
2608
2609     // Next, call with a queue family index that's too large:
2610     uint32_t queueFamilyIndex[2] = {100000, 0};
2611     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2612     swapchain_create_info.queueFamilyIndexCount = 2;
2613     swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
2614     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2615     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2616     pass = (err != VK_SUCCESS);
2617     ASSERT_TRUE(pass);
2618     m_errorMonitor->VerifyFound();
2619
2620     // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
2621     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2622     swapchain_create_info.queueFamilyIndexCount = 1;
2623     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2624                                          "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
2625                                          "pCreateInfo->pQueueFamilyIndices).");
2626     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2627     pass = (err != VK_SUCCESS);
2628     ASSERT_TRUE(pass);
2629     m_errorMonitor->VerifyFound();
2630
2631     // Next, call with an invalid imageSharingMode:
2632     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
2633     swapchain_create_info.queueFamilyIndexCount = 1;
2634     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2635                                          "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
2636     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2637     pass = (err != VK_SUCCESS);
2638     ASSERT_TRUE(pass);
2639     m_errorMonitor->VerifyFound();
2640     // Fix for the future:
2641     // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2642     // SUPPORTED
2643     swapchain_create_info.queueFamilyIndexCount = 0;
2644     queueFamilyIndex[0] = 0;
2645     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
2646
2647     // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
2648     // Get the images from a swapchain:
2649     // Acquire an image from a swapchain:
2650     // Present an image to a swapchain:
2651     // Destroy the swapchain:
2652
2653     // TODOs:
2654     //
2655     // - Try destroying the device without first destroying the swapchain
2656     //
2657     // - Try destroying the device without first destroying the surface
2658     //
2659     // - Try destroying the surface without first destroying the swapchain
2660
2661     // Destroy the surface:
2662     vkDestroySurfaceKHR(instance(), surface, NULL);
2663
2664     // Tear down the window:
2665     xcb_destroy_window(connection, xcb_window);
2666     xcb_disconnect(connection);
2667
2668 #else  // VK_USE_PLATFORM_XCB_KHR
2669     return;
2670 #endif // VK_USE_PLATFORM_XCB_KHR
2671 }
2672
2673 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2674     VkResult err;
2675     bool pass;
2676
2677     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2678                                          "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2679
2680     ASSERT_NO_FATAL_FAILURE(InitState());
2681
2682     // Create an image, allocate memory, free it, and then try to bind it
2683     VkImage image;
2684     VkDeviceMemory mem;
2685     VkMemoryRequirements mem_reqs;
2686
2687     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2688     const int32_t tex_width = 32;
2689     const int32_t tex_height = 32;
2690
2691     VkImageCreateInfo image_create_info = {};
2692     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2693     image_create_info.pNext = NULL;
2694     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2695     image_create_info.format = tex_format;
2696     image_create_info.extent.width = tex_width;
2697     image_create_info.extent.height = tex_height;
2698     image_create_info.extent.depth = 1;
2699     image_create_info.mipLevels = 1;
2700     image_create_info.arrayLayers = 1;
2701     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2702     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2703     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2704     image_create_info.flags = 0;
2705     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2706
2707     VkMemoryAllocateInfo mem_alloc = {};
2708     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2709     mem_alloc.pNext = NULL;
2710     mem_alloc.allocationSize = 0;
2711
2712     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2713     ASSERT_VK_SUCCESS(err);
2714
2715     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2716
2717     mem_alloc.allocationSize = mem_reqs.size;
2718
2719     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2720     if (!pass) { // If we can't find any unmappable memory this test doesn't
2721                  // make sense
2722         vkDestroyImage(m_device->device(), image, NULL);
2723         return;
2724     }
2725
2726     // allocate memory
2727     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2728     ASSERT_VK_SUCCESS(err);
2729
2730     // Try to bind free memory that has been freed
2731     err = vkBindImageMemory(m_device->device(), image, mem, 0);
2732     ASSERT_VK_SUCCESS(err);
2733
2734     // Map memory as if to initialize the image
2735     void *mappedAddress = NULL;
2736     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2737
2738     m_errorMonitor->VerifyFound();
2739
2740     vkDestroyImage(m_device->device(), image, NULL);
2741     vkFreeMemory(m_device->device(), mem, NULL);
2742 }
2743
2744 TEST_F(VkLayerTest, RebindMemory) {
2745     VkResult err;
2746     bool pass;
2747
2748     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2749
2750     ASSERT_NO_FATAL_FAILURE(InitState());
2751
2752     // Create an image, allocate memory, free it, and then try to bind it
2753     VkImage image;
2754     VkDeviceMemory mem1;
2755     VkDeviceMemory mem2;
2756     VkMemoryRequirements mem_reqs;
2757
2758     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2759     const int32_t tex_width = 32;
2760     const int32_t tex_height = 32;
2761
2762     VkImageCreateInfo image_create_info = {};
2763     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2764     image_create_info.pNext = NULL;
2765     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2766     image_create_info.format = tex_format;
2767     image_create_info.extent.width = tex_width;
2768     image_create_info.extent.height = tex_height;
2769     image_create_info.extent.depth = 1;
2770     image_create_info.mipLevels = 1;
2771     image_create_info.arrayLayers = 1;
2772     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2773     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2774     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2775     image_create_info.flags = 0;
2776
2777     VkMemoryAllocateInfo mem_alloc = {};
2778     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2779     mem_alloc.pNext = NULL;
2780     mem_alloc.allocationSize = 0;
2781     mem_alloc.memoryTypeIndex = 0;
2782
2783     // Introduce failure, do NOT set memProps to
2784     // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2785     mem_alloc.memoryTypeIndex = 1;
2786     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2787     ASSERT_VK_SUCCESS(err);
2788
2789     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2790
2791     mem_alloc.allocationSize = mem_reqs.size;
2792     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2793     ASSERT_TRUE(pass);
2794
2795     // allocate 2 memory objects
2796     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2797     ASSERT_VK_SUCCESS(err);
2798     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2799     ASSERT_VK_SUCCESS(err);
2800
2801     // Bind first memory object to Image object
2802     err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2803     ASSERT_VK_SUCCESS(err);
2804
2805     // Introduce validation failure, try to bind a different memory object to
2806     // the same image object
2807     err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2808
2809     m_errorMonitor->VerifyFound();
2810
2811     vkDestroyImage(m_device->device(), image, NULL);
2812     vkFreeMemory(m_device->device(), mem1, NULL);
2813     vkFreeMemory(m_device->device(), mem2, NULL);
2814 }
2815
2816 TEST_F(VkLayerTest, SubmitSignaledFence) {
2817     vk_testing::Fence testFence;
2818
2819     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state.  Fences "
2820                                                                         "must be reset before being submitted");
2821
2822     VkFenceCreateInfo fenceInfo = {};
2823     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2824     fenceInfo.pNext = NULL;
2825     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2826
2827     ASSERT_NO_FATAL_FAILURE(InitState());
2828     ASSERT_NO_FATAL_FAILURE(InitViewport());
2829     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2830
2831     BeginCommandBuffer();
2832     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
2833     EndCommandBuffer();
2834
2835     testFence.init(*m_device, fenceInfo);
2836
2837     VkSubmitInfo submit_info;
2838     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2839     submit_info.pNext = NULL;
2840     submit_info.waitSemaphoreCount = 0;
2841     submit_info.pWaitSemaphores = NULL;
2842     submit_info.pWaitDstStageMask = NULL;
2843     submit_info.commandBufferCount = 1;
2844     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2845     submit_info.signalSemaphoreCount = 0;
2846     submit_info.pSignalSemaphores = NULL;
2847
2848     vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2849     vkQueueWaitIdle(m_device->m_queue);
2850
2851     m_errorMonitor->VerifyFound();
2852 }
2853 // This is a positive test. We used to expect error in this case but spec now
2854 // allows it
2855 TEST_F(VkLayerTest, ResetUnsignaledFence) {
2856     m_errorMonitor->ExpectSuccess();
2857     vk_testing::Fence testFence;
2858     VkFenceCreateInfo fenceInfo = {};
2859     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2860     fenceInfo.pNext = NULL;
2861
2862     ASSERT_NO_FATAL_FAILURE(InitState());
2863     testFence.init(*m_device, fenceInfo);
2864     VkFence fences[1] = {testFence.handle()};
2865     VkResult result = vkResetFences(m_device->device(), 1, fences);
2866     ASSERT_VK_SUCCESS(result);
2867
2868     m_errorMonitor->VerifyNotFound();
2869 }
2870 #if 0 // A few devices have issues with this test so disabling for now
2871 TEST_F(VkLayerTest, LongFenceChain)
2872 {
2873     m_errorMonitor->ExpectSuccess();
2874
2875     ASSERT_NO_FATAL_FAILURE(InitState());
2876     VkResult err;
2877
2878     std::vector<VkFence> fences;
2879
2880     const int chainLength = 32768;
2881
2882     for (int i = 0; i < chainLength; i++) {
2883         VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2884         VkFence fence;
2885         err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2886         ASSERT_VK_SUCCESS(err);
2887
2888         fences.push_back(fence);
2889
2890         VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
2891             0, nullptr, 0, nullptr };
2892         err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2893         ASSERT_VK_SUCCESS(err);
2894
2895     }
2896
2897     // BOOM, stack overflow.
2898     vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
2899
2900     for (auto fence : fences)
2901         vkDestroyFence(m_device->device(), fence, nullptr);
2902
2903     m_errorMonitor->VerifyNotFound();
2904 }
2905 #endif
2906 TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
2907     m_errorMonitor->ExpectSuccess();
2908
2909     ASSERT_NO_FATAL_FAILURE(InitState());
2910     VkResult err;
2911
2912     // Record (empty!) command buffer that can be submitted multiple times
2913     // simultaneously.
2914     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2915                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
2916     m_commandBuffer->BeginCommandBuffer(&cbbi);
2917     m_commandBuffer->EndCommandBuffer();
2918
2919     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2920     VkFence fence;
2921     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2922     ASSERT_VK_SUCCESS(err);
2923
2924     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
2925     VkSemaphore s1, s2;
2926     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
2927     ASSERT_VK_SUCCESS(err);
2928     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
2929     ASSERT_VK_SUCCESS(err);
2930
2931     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
2932     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
2933     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2934     ASSERT_VK_SUCCESS(err);
2935
2936     // Submit CB again, signaling s2.
2937     si.pSignalSemaphores = &s2;
2938     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2939     ASSERT_VK_SUCCESS(err);
2940
2941     // Wait for fence.
2942     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
2943     ASSERT_VK_SUCCESS(err);
2944
2945     // CB is still in flight from second submission, but semaphore s1 is no
2946     // longer in flight. delete it.
2947     vkDestroySemaphore(m_device->device(), s1, nullptr);
2948
2949     m_errorMonitor->VerifyNotFound();
2950
2951     // Force device idle and clean up remaining objects
2952     vkDeviceWaitIdle(m_device->device());
2953     vkDestroySemaphore(m_device->device(), s2, nullptr);
2954     vkDestroyFence(m_device->device(), fence, nullptr);
2955 }
2956
2957 TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
2958     m_errorMonitor->ExpectSuccess();
2959
2960     ASSERT_NO_FATAL_FAILURE(InitState());
2961     VkResult err;
2962
2963     // A fence created signaled
2964     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
2965     VkFence f1;
2966     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
2967     ASSERT_VK_SUCCESS(err);
2968
2969     // A fence created not
2970     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2971     VkFence f2;
2972     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
2973     ASSERT_VK_SUCCESS(err);
2974
2975     // Submit the unsignaled fence
2976     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
2977     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
2978
2979     // Wait on both fences, with signaled first.
2980     VkFence fences[] = {f1, f2};
2981     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
2982
2983     // Should have both retired!
2984     vkDestroyFence(m_device->device(), f1, nullptr);
2985     vkDestroyFence(m_device->device(), f2, nullptr);
2986
2987     m_errorMonitor->VerifyNotFound();
2988 }
2989
2990 TEST_F(VkLayerTest, InvalidUsageBits) {
2991     TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
2992                      "Initialize buffer with wrong usage then perform copy expecting errors "
2993                      "from both the image and the buffer (2 calls)");
2994     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
2995
2996     ASSERT_NO_FATAL_FAILURE(InitState());
2997     VkImageObj image(m_device);
2998     // Initialize image with USAGE_TRANSIENT_ATTACHMENT
2999     image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3000     ASSERT_TRUE(image.initialized());
3001
3002     VkImageView dsv;
3003     VkImageViewCreateInfo dsvci = {};
3004     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3005     dsvci.image = image.handle();
3006     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3007     dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
3008     dsvci.subresourceRange.layerCount = 1;
3009     dsvci.subresourceRange.baseMipLevel = 0;
3010     dsvci.subresourceRange.levelCount = 1;
3011     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3012
3013     // Create a view with depth / stencil aspect for image with different usage
3014     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3015
3016     m_errorMonitor->VerifyFound();
3017
3018     // Initialize buffer with TRANSFER_DST usage
3019     vk_testing::Buffer buffer;
3020     VkMemoryPropertyFlags reqs = 0;
3021     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3022     VkBufferImageCopy region = {};
3023     region.bufferRowLength = 128;
3024     region.bufferImageHeight = 128;
3025     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3026     region.imageSubresource.layerCount = 1;
3027     region.imageExtent.height = 16;
3028     region.imageExtent.width = 16;
3029     region.imageExtent.depth = 1;
3030
3031     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
3032     // Buffer usage not set to TRANSFER_SRC and image usage not set to
3033     // TRANSFER_DST
3034     BeginCommandBuffer();
3035     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3036                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3037     m_errorMonitor->VerifyFound();
3038
3039     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3040     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3041                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3042     m_errorMonitor->VerifyFound();
3043 }
3044
3045 TEST_F(VkLayerTest, ValidUsage) {
3046     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
3047                      "doesn't generate validation errors");
3048
3049     ASSERT_NO_FATAL_FAILURE(InitState());
3050
3051     m_errorMonitor->ExpectSuccess();
3052     // Verify that we can create a view with usage INPUT_ATTACHMENT
3053     VkImageObj image(m_device);
3054     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3055     ASSERT_TRUE(image.initialized());
3056     VkImageView imageView;
3057     VkImageViewCreateInfo ivci = {};
3058     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3059     ivci.image = image.handle();
3060     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3061     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3062     ivci.subresourceRange.layerCount = 1;
3063     ivci.subresourceRange.baseMipLevel = 0;
3064     ivci.subresourceRange.levelCount = 1;
3065     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3066
3067     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3068     m_errorMonitor->VerifyNotFound();
3069     vkDestroyImageView(m_device->device(), imageView, NULL);
3070 }
3071 #endif // MEM_TRACKER_TESTS
3072
3073 #if OBJ_TRACKER_TESTS
3074
3075 TEST_F(VkLayerTest, LeakAnObject) {
3076     VkResult err;
3077
3078     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3079
3080     // Note that we have to create a new device since destroying the
3081     // framework's device causes Teardown() to fail and just calling Teardown
3082     // will destroy the errorMonitor.
3083
3084     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3085
3086     ASSERT_NO_FATAL_FAILURE(InitState());
3087
3088     const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
3089     std::vector<VkDeviceQueueCreateInfo> queue_info;
3090     queue_info.reserve(queue_props.size());
3091     std::vector<std::vector<float>> queue_priorities;
3092     for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
3093         VkDeviceQueueCreateInfo qi = {};
3094         qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3095         qi.pNext = NULL;
3096         qi.queueFamilyIndex = i;
3097         qi.queueCount = queue_props[i].queueCount;
3098         queue_priorities.emplace_back(qi.queueCount, 0.0f);
3099         qi.pQueuePriorities = queue_priorities[i].data();
3100         queue_info.push_back(qi);
3101     }
3102
3103     std::vector<const char *> device_extension_names;
3104
3105     // The sacrificial device object
3106     VkDevice testDevice;
3107     VkDeviceCreateInfo device_create_info = {};
3108     auto features = m_device->phy().features();
3109     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3110     device_create_info.pNext = NULL;
3111     device_create_info.queueCreateInfoCount = queue_info.size();
3112     device_create_info.pQueueCreateInfos = queue_info.data();
3113     device_create_info.enabledLayerCount = 0;
3114     device_create_info.ppEnabledLayerNames = NULL;
3115     device_create_info.pEnabledFeatures = &features;
3116     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3117     ASSERT_VK_SUCCESS(err);
3118
3119     VkFence fence;
3120     VkFenceCreateInfo fence_create_info = {};
3121     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3122     fence_create_info.pNext = NULL;
3123     fence_create_info.flags = 0;
3124     err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3125     ASSERT_VK_SUCCESS(err);
3126
3127     // Induce failure by not calling vkDestroyFence
3128     vkDestroyDevice(testDevice, NULL);
3129     m_errorMonitor->VerifyFound();
3130 }
3131
3132 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3133
3134     TEST_DESCRIPTION("Allocate command buffers from one command pool and "
3135                      "attempt to delete them from another.");
3136
3137     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3138
3139     ASSERT_NO_FATAL_FAILURE(InitState());
3140     VkCommandPool command_pool_one;
3141     VkCommandPool command_pool_two;
3142
3143     VkCommandPoolCreateInfo pool_create_info{};
3144     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3145     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3146     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3147
3148     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3149
3150     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3151
3152     VkCommandBuffer command_buffer[9];
3153     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3154     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3155     command_buffer_allocate_info.commandPool = command_pool_one;
3156     command_buffer_allocate_info.commandBufferCount = 9;
3157     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3158     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3159
3160     vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]);
3161
3162     m_errorMonitor->VerifyFound();
3163
3164     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3165     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3166 }
3167
3168 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3169     VkResult err;
3170
3171     TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and "
3172                      "attempt to delete them from another.");
3173
3174     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3175
3176     ASSERT_NO_FATAL_FAILURE(InitState());
3177     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3178
3179     VkDescriptorPoolSize ds_type_count = {};
3180     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3181     ds_type_count.descriptorCount = 1;
3182
3183     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3184     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3185     ds_pool_ci.pNext = NULL;
3186     ds_pool_ci.flags = 0;
3187     ds_pool_ci.maxSets = 1;
3188     ds_pool_ci.poolSizeCount = 1;
3189     ds_pool_ci.pPoolSizes = &ds_type_count;
3190
3191     VkDescriptorPool ds_pool_one;
3192     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
3193     ASSERT_VK_SUCCESS(err);
3194
3195     // Create a second descriptor pool
3196     VkDescriptorPool ds_pool_two;
3197     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two);
3198     ASSERT_VK_SUCCESS(err);
3199
3200     VkDescriptorSetLayoutBinding dsl_binding = {};
3201     dsl_binding.binding = 0;
3202     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3203     dsl_binding.descriptorCount = 1;
3204     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3205     dsl_binding.pImmutableSamplers = NULL;
3206
3207     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3208     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3209     ds_layout_ci.pNext = NULL;
3210     ds_layout_ci.bindingCount = 1;
3211     ds_layout_ci.pBindings = &dsl_binding;
3212
3213     VkDescriptorSetLayout ds_layout;
3214     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3215     ASSERT_VK_SUCCESS(err);
3216
3217     VkDescriptorSet descriptorSet;
3218     VkDescriptorSetAllocateInfo alloc_info = {};
3219     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3220     alloc_info.descriptorSetCount = 1;
3221     alloc_info.descriptorPool = ds_pool_one;
3222     alloc_info.pSetLayouts = &ds_layout;
3223     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3224     ASSERT_VK_SUCCESS(err);
3225
3226     err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet);
3227
3228     m_errorMonitor->VerifyFound();
3229
3230     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3231     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
3232     vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL);
3233 }
3234
3235 TEST_F(VkLayerTest, CreateUnknownObject) {
3236     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3237
3238     TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3239
3240     ASSERT_NO_FATAL_FAILURE(InitState());
3241
3242     // Pass bogus handle into GetImageMemoryRequirements
3243     VkMemoryRequirements mem_reqs;
3244     uint64_t fakeImageHandle = 0xCADECADE;
3245     VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3246
3247     vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3248
3249     m_errorMonitor->VerifyFound();
3250 }
3251
3252 TEST_F(VkLayerTest, PipelineNotBound) {
3253     VkResult err;
3254
3255     TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3256
3257     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object ");
3258
3259     ASSERT_NO_FATAL_FAILURE(InitState());
3260     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3261
3262     VkDescriptorPoolSize ds_type_count = {};
3263     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3264     ds_type_count.descriptorCount = 1;
3265
3266     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3267     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3268     ds_pool_ci.pNext = NULL;
3269     ds_pool_ci.maxSets = 1;
3270     ds_pool_ci.poolSizeCount = 1;
3271     ds_pool_ci.pPoolSizes = &ds_type_count;
3272
3273     VkDescriptorPool ds_pool;
3274     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
3275     ASSERT_VK_SUCCESS(err);
3276
3277     VkDescriptorSetLayoutBinding dsl_binding = {};
3278     dsl_binding.binding = 0;
3279     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3280     dsl_binding.descriptorCount = 1;
3281     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3282     dsl_binding.pImmutableSamplers = NULL;
3283
3284     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3285     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3286     ds_layout_ci.pNext = NULL;
3287     ds_layout_ci.bindingCount = 1;
3288     ds_layout_ci.pBindings = &dsl_binding;
3289
3290     VkDescriptorSetLayout ds_layout;
3291     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3292     ASSERT_VK_SUCCESS(err);
3293
3294     VkDescriptorSet descriptorSet;
3295     VkDescriptorSetAllocateInfo alloc_info = {};
3296     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3297     alloc_info.descriptorSetCount = 1;
3298     alloc_info.descriptorPool = ds_pool;
3299     alloc_info.pSetLayouts = &ds_layout;
3300     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3301     ASSERT_VK_SUCCESS(err);
3302
3303     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
3304     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3305     pipeline_layout_ci.pNext = NULL;
3306     pipeline_layout_ci.setLayoutCount = 1;
3307     pipeline_layout_ci.pSetLayouts = &ds_layout;
3308
3309     VkPipelineLayout pipeline_layout;
3310     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
3311     ASSERT_VK_SUCCESS(err);
3312
3313     VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3314
3315     BeginCommandBuffer();
3316     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3317
3318     m_errorMonitor->VerifyFound();
3319
3320     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
3321     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3322     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
3323 }
3324
3325 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3326     VkResult err;
3327
3328     TEST_DESCRIPTION("Test validation check for an invalid memory type index "
3329                      "during bind[Buffer|Image]Memory time");
3330
3331     ASSERT_NO_FATAL_FAILURE(InitState());
3332
3333     // Create an image, allocate memory, set a bad typeIndex and then try to
3334     // bind it
3335     VkImage image;
3336     VkDeviceMemory mem;
3337     VkMemoryRequirements mem_reqs;
3338     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3339     const int32_t tex_width = 32;
3340     const int32_t tex_height = 32;
3341
3342     VkImageCreateInfo image_create_info = {};
3343     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3344     image_create_info.pNext = NULL;
3345     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3346     image_create_info.format = tex_format;
3347     image_create_info.extent.width = tex_width;
3348     image_create_info.extent.height = tex_height;
3349     image_create_info.extent.depth = 1;
3350     image_create_info.mipLevels = 1;
3351     image_create_info.arrayLayers = 1;
3352     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3353     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3354     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3355     image_create_info.flags = 0;
3356
3357     VkMemoryAllocateInfo mem_alloc = {};
3358     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3359     mem_alloc.pNext = NULL;
3360     mem_alloc.allocationSize = 0;
3361     mem_alloc.memoryTypeIndex = 0;
3362
3363     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3364     ASSERT_VK_SUCCESS(err);
3365
3366     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3367     mem_alloc.allocationSize = mem_reqs.size;
3368
3369     // Introduce Failure, select invalid TypeIndex
3370     VkPhysicalDeviceMemoryProperties memory_info;
3371
3372     vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3373     unsigned int i;
3374     for (i = 0; i < memory_info.memoryTypeCount; i++) {
3375         if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3376             mem_alloc.memoryTypeIndex = i;
3377             break;
3378         }
3379     }
3380     if (i >= memory_info.memoryTypeCount) {
3381         printf("No invalid memory type index could be found; skipped.\n");
3382         vkDestroyImage(m_device->device(), image, NULL);
3383         return;
3384     }
3385
3386     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3387
3388     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3389     ASSERT_VK_SUCCESS(err);
3390
3391     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3392     (void)err;
3393
3394     m_errorMonitor->VerifyFound();
3395
3396     vkDestroyImage(m_device->device(), image, NULL);
3397     vkFreeMemory(m_device->device(), mem, NULL);
3398 }
3399
3400 TEST_F(VkLayerTest, BindInvalidMemory) {
3401     VkResult err;
3402     bool pass;
3403
3404     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object ");
3405
3406     ASSERT_NO_FATAL_FAILURE(InitState());
3407
3408     // Create an image, allocate memory, free it, and then try to bind it
3409     VkImage image;
3410     VkDeviceMemory mem;
3411     VkMemoryRequirements mem_reqs;
3412
3413     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3414     const int32_t tex_width = 32;
3415     const int32_t tex_height = 32;
3416
3417     VkImageCreateInfo image_create_info = {};
3418     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3419     image_create_info.pNext = NULL;
3420     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3421     image_create_info.format = tex_format;
3422     image_create_info.extent.width = tex_width;
3423     image_create_info.extent.height = tex_height;
3424     image_create_info.extent.depth = 1;
3425     image_create_info.mipLevels = 1;
3426     image_create_info.arrayLayers = 1;
3427     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3428     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3429     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3430     image_create_info.flags = 0;
3431
3432     VkMemoryAllocateInfo mem_alloc = {};
3433     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3434     mem_alloc.pNext = NULL;
3435     mem_alloc.allocationSize = 0;
3436     mem_alloc.memoryTypeIndex = 0;
3437
3438     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3439     ASSERT_VK_SUCCESS(err);
3440
3441     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3442
3443     mem_alloc.allocationSize = mem_reqs.size;
3444
3445     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3446     ASSERT_TRUE(pass);
3447
3448     // allocate memory
3449     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3450     ASSERT_VK_SUCCESS(err);
3451
3452     // Introduce validation failure, free memory before binding
3453     vkFreeMemory(m_device->device(), mem, NULL);
3454
3455     // Try to bind free memory that has been freed
3456     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3457     // This may very well return an error.
3458     (void)err;
3459
3460     m_errorMonitor->VerifyFound();
3461
3462     vkDestroyImage(m_device->device(), image, NULL);
3463 }
3464
3465 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3466     VkResult err;
3467     bool pass;
3468
3469     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3470
3471     ASSERT_NO_FATAL_FAILURE(InitState());
3472
3473     // Create an image object, allocate memory, destroy the object and then try
3474     // to bind it
3475     VkImage image;
3476     VkDeviceMemory mem;
3477     VkMemoryRequirements mem_reqs;
3478
3479     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3480     const int32_t tex_width = 32;
3481     const int32_t tex_height = 32;
3482
3483     VkImageCreateInfo image_create_info = {};
3484     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3485     image_create_info.pNext = NULL;
3486     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3487     image_create_info.format = tex_format;
3488     image_create_info.extent.width = tex_width;
3489     image_create_info.extent.height = tex_height;
3490     image_create_info.extent.depth = 1;
3491     image_create_info.mipLevels = 1;
3492     image_create_info.arrayLayers = 1;
3493     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3494     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3495     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3496     image_create_info.flags = 0;
3497
3498     VkMemoryAllocateInfo mem_alloc = {};
3499     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3500     mem_alloc.pNext = NULL;
3501     mem_alloc.allocationSize = 0;
3502     mem_alloc.memoryTypeIndex = 0;
3503
3504     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3505     ASSERT_VK_SUCCESS(err);
3506
3507     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3508
3509     mem_alloc.allocationSize = mem_reqs.size;
3510     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3511     ASSERT_TRUE(pass);
3512
3513     // Allocate memory
3514     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3515     ASSERT_VK_SUCCESS(err);
3516
3517     // Introduce validation failure, destroy Image object before binding
3518     vkDestroyImage(m_device->device(), image, NULL);
3519     ASSERT_VK_SUCCESS(err);
3520
3521     // Now Try to bind memory to this destroyed object
3522     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3523     // This may very well return an error.
3524     (void)err;
3525
3526     m_errorMonitor->VerifyFound();
3527
3528     vkFreeMemory(m_device->device(), mem, NULL);
3529 }
3530
3531 #endif // OBJ_TRACKER_TESTS
3532
3533 #if DRAW_STATE_TESTS
3534
3535 TEST_F(VkLayerTest, ImageSampleCounts) {
3536
3537     TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger "
3538                      "validation errors.");
3539     ASSERT_NO_FATAL_FAILURE(InitState());
3540
3541     VkMemoryPropertyFlags reqs = 0;
3542     VkImageCreateInfo image_create_info = {};
3543     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3544     image_create_info.pNext = NULL;
3545     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3546     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3547     image_create_info.extent.width = 256;
3548     image_create_info.extent.height = 256;
3549     image_create_info.extent.depth = 1;
3550     image_create_info.mipLevels = 1;
3551     image_create_info.arrayLayers = 1;
3552     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3553     image_create_info.flags = 0;
3554
3555     VkImageBlit blit_region = {};
3556     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3557     blit_region.srcSubresource.baseArrayLayer = 0;
3558     blit_region.srcSubresource.layerCount = 1;
3559     blit_region.srcSubresource.mipLevel = 0;
3560     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3561     blit_region.dstSubresource.baseArrayLayer = 0;
3562     blit_region.dstSubresource.layerCount = 1;
3563     blit_region.dstSubresource.mipLevel = 0;
3564
3565     // Create two images, the source with sampleCount = 2, and attempt to blit
3566     // between them
3567     {
3568         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3569         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3570         vk_testing::Image src_image;
3571         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3572         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3573         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3574         vk_testing::Image dst_image;
3575         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3576         m_commandBuffer->BeginCommandBuffer();
3577         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3578                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3579                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3580         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3581                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3582         m_errorMonitor->VerifyFound();
3583         m_commandBuffer->EndCommandBuffer();
3584     }
3585
3586     // Create two images, the dest with sampleCount = 4, and attempt to blit
3587     // between them
3588     {
3589         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3590         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3591         vk_testing::Image src_image;
3592         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3593         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3594         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3595         vk_testing::Image dst_image;
3596         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3597         m_commandBuffer->BeginCommandBuffer();
3598         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3599                                                                             "of VK_SAMPLE_COUNT_4_BIT but "
3600                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3601         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3602                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3603         m_errorMonitor->VerifyFound();
3604         m_commandBuffer->EndCommandBuffer();
3605     }
3606
3607     VkBufferImageCopy copy_region = {};
3608     copy_region.bufferRowLength = 128;
3609     copy_region.bufferImageHeight = 128;
3610     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3611     copy_region.imageSubresource.layerCount = 1;
3612     copy_region.imageExtent.height = 64;
3613     copy_region.imageExtent.width = 64;
3614     copy_region.imageExtent.depth = 1;
3615
3616     // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3617     // buffer to image
3618     {
3619         vk_testing::Buffer src_buffer;
3620         VkMemoryPropertyFlags reqs = 0;
3621         src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3622         image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
3623         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3624         vk_testing::Image dst_image;
3625         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3626         m_commandBuffer->BeginCommandBuffer();
3627         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3628                                                                             "of VK_SAMPLE_COUNT_8_BIT but "
3629                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3630         vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(),
3631                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
3632         m_errorMonitor->VerifyFound();
3633         m_commandBuffer->EndCommandBuffer();
3634     }
3635
3636     // Create dst buffer and src image with sampleCount = 2 and attempt to copy
3637     // image to buffer
3638     {
3639         vk_testing::Buffer dst_buffer;
3640         dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3641         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3642         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3643         vk_testing::Image src_image;
3644         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3645         m_commandBuffer->BeginCommandBuffer();
3646         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3647                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3648                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3649         vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3650                                dst_buffer.handle(), 1, &copy_region);
3651         m_errorMonitor->VerifyFound();
3652         m_commandBuffer->EndCommandBuffer();
3653     }
3654 }
3655
3656 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
3657     VkResult err;
3658     bool pass;
3659
3660     TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
3661     ASSERT_NO_FATAL_FAILURE(InitState());
3662
3663     // If w/d/h granularity is 1, test is not meaningful
3664     // TODO: When virtual device limits are available, create a set of limits for this test that
3665     // will always have a granularity of > 1 for w, h, and d
3666     auto index = m_device->graphics_queue_node_index_;
3667     auto queue_family_properties = m_device->phy().queue_properties();
3668
3669     if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
3670         (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
3671         (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
3672         return;
3673     }
3674
3675     // Create two images of different types and try to copy between them
3676     VkImage srcImage;
3677     VkImage dstImage;
3678     VkDeviceMemory srcMem;
3679     VkDeviceMemory destMem;
3680     VkMemoryRequirements memReqs;
3681
3682     VkImageCreateInfo image_create_info = {};
3683     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3684     image_create_info.pNext = NULL;
3685     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3686     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3687     image_create_info.extent.width = 32;
3688     image_create_info.extent.height = 32;
3689     image_create_info.extent.depth = 1;
3690     image_create_info.mipLevels = 1;
3691     image_create_info.arrayLayers = 4;
3692     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3693     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3694     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3695     image_create_info.flags = 0;
3696
3697     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
3698     ASSERT_VK_SUCCESS(err);
3699
3700     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
3701     ASSERT_VK_SUCCESS(err);
3702
3703     // Allocate memory
3704     VkMemoryAllocateInfo memAlloc = {};
3705     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3706     memAlloc.pNext = NULL;
3707     memAlloc.allocationSize = 0;
3708     memAlloc.memoryTypeIndex = 0;
3709
3710     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
3711     memAlloc.allocationSize = memReqs.size;
3712     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3713     ASSERT_TRUE(pass);
3714     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
3715     ASSERT_VK_SUCCESS(err);
3716
3717     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
3718     memAlloc.allocationSize = memReqs.size;
3719     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3720     ASSERT_VK_SUCCESS(err);
3721     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
3722     ASSERT_VK_SUCCESS(err);
3723
3724     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
3725     ASSERT_VK_SUCCESS(err);
3726     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
3727     ASSERT_VK_SUCCESS(err);
3728
3729     BeginCommandBuffer();
3730     VkImageCopy copyRegion;
3731     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3732     copyRegion.srcSubresource.mipLevel = 0;
3733     copyRegion.srcSubresource.baseArrayLayer = 0;
3734     copyRegion.srcSubresource.layerCount = 1;
3735     copyRegion.srcOffset.x = 0;
3736     copyRegion.srcOffset.y = 0;
3737     copyRegion.srcOffset.z = 0;
3738     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3739     copyRegion.dstSubresource.mipLevel = 0;
3740     copyRegion.dstSubresource.baseArrayLayer = 0;
3741     copyRegion.dstSubresource.layerCount = 1;
3742     copyRegion.dstOffset.x = 0;
3743     copyRegion.dstOffset.y = 0;
3744     copyRegion.dstOffset.z = 0;
3745     copyRegion.extent.width = 1;
3746     copyRegion.extent.height = 1;
3747     copyRegion.extent.depth = 1;
3748
3749     // Introduce failure by setting srcOffset to a bad granularity value
3750     copyRegion.srcOffset.y = 3;
3751     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3752     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3753     m_errorMonitor->VerifyFound();
3754
3755     // Introduce failure by setting extent to a bad granularity value
3756     copyRegion.srcOffset.y = 0;
3757     copyRegion.extent.width = 3;
3758     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3759     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3760     m_errorMonitor->VerifyFound();
3761
3762     // Now do some buffer/image copies
3763     vk_testing::Buffer buffer;
3764     VkMemoryPropertyFlags reqs = 0;
3765     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3766     VkBufferImageCopy region = {};
3767     region.bufferOffset = 0;
3768     region.bufferRowLength = 3;
3769     region.bufferImageHeight = 128;
3770     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3771     region.imageSubresource.layerCount = 1;
3772     region.imageExtent.height = 16;
3773     region.imageExtent.width = 16;
3774     region.imageExtent.depth = 1;
3775     region.imageOffset.x = 0;
3776     region.imageOffset.y = 0;
3777     region.imageOffset.z = 0;
3778
3779     // Introduce failure by setting bufferRowLength to a bad granularity value
3780     region.bufferRowLength = 3;
3781     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3782     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3783                            &region);
3784     m_errorMonitor->VerifyFound();
3785     region.bufferRowLength = 128;
3786
3787     // Introduce failure by setting bufferOffset to a bad granularity value
3788     region.bufferOffset = 3;
3789     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3790     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3791                            &region);
3792     m_errorMonitor->VerifyFound();
3793     region.bufferOffset = 0;
3794
3795     // Introduce failure by setting bufferImageHeight to a bad granularity value
3796     region.bufferImageHeight = 3;
3797     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3798     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3799                            &region);
3800     m_errorMonitor->VerifyFound();
3801     region.bufferImageHeight = 128;
3802
3803     // Introduce failure by setting imageExtent to a bad granularity value
3804     region.imageExtent.width = 3;
3805     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3806     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3807                            &region);
3808     m_errorMonitor->VerifyFound();
3809     region.imageExtent.width = 16;
3810
3811     // Introduce failure by setting imageOffset to a bad granularity value
3812     region.imageOffset.z = 3;
3813     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3814     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3815                            &region);
3816     m_errorMonitor->VerifyFound();
3817
3818     EndCommandBuffer();
3819
3820     vkDestroyImage(m_device->device(), srcImage, NULL);
3821     vkDestroyImage(m_device->device(), dstImage, NULL);
3822     vkFreeMemory(m_device->device(), srcMem, NULL);
3823     vkFreeMemory(m_device->device(), destMem, NULL);
3824 }
3825
3826 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
3827     TEST_DESCRIPTION("Submit command buffer created using one queue family and "
3828                      "attempt to submit them on a queue created in a different "
3829                      "queue family.");
3830
3831     ASSERT_NO_FATAL_FAILURE(InitState());
3832     // This test is meaningless unless we have multiple queue families
3833     auto queue_family_properties = m_device->phy().queue_properties();
3834     if (queue_family_properties.size() < 2) {
3835         return;
3836     }
3837     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue ");
3838     // Get safe index of another queue family
3839     uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
3840     ASSERT_NO_FATAL_FAILURE(InitState());
3841     // Create a second queue using a different queue family
3842     VkQueue other_queue;
3843     vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
3844
3845     // Record an empty cmd buffer
3846     VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3847     cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3848     vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
3849     vkEndCommandBuffer(m_commandBuffer->handle());
3850
3851     // And submit on the wrong queue
3852     VkSubmitInfo submit_info = {};
3853     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3854     submit_info.commandBufferCount = 1;
3855     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3856     vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
3857
3858     m_errorMonitor->VerifyFound();
3859 }
3860
3861 TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
3862     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
3863                      "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
3864                      "the command buffer has prior knowledge of that "
3865                      "attachment's layout.");
3866
3867     m_errorMonitor->ExpectSuccess();
3868
3869     ASSERT_NO_FATAL_FAILURE(InitState());
3870
3871     // A renderpass with one color attachment.
3872     VkAttachmentDescription attachment = {0,
3873                                           VK_FORMAT_R8G8B8A8_UNORM,
3874                                           VK_SAMPLE_COUNT_1_BIT,
3875                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3876                                           VK_ATTACHMENT_STORE_OP_STORE,
3877                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3878                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3879                                           VK_IMAGE_LAYOUT_UNDEFINED,
3880                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3881
3882     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3883
3884     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3885
3886     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3887
3888     VkRenderPass rp;
3889     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3890     ASSERT_VK_SUCCESS(err);
3891
3892     // A compatible framebuffer.
3893     VkImageObj image(m_device);
3894     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3895     ASSERT_TRUE(image.initialized());
3896
3897     VkImageViewCreateInfo ivci = {
3898         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3899         nullptr,
3900         0,
3901         image.handle(),
3902         VK_IMAGE_VIEW_TYPE_2D,
3903         VK_FORMAT_R8G8B8A8_UNORM,
3904         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3905          VK_COMPONENT_SWIZZLE_IDENTITY},
3906         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3907     };
3908     VkImageView view;
3909     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3910     ASSERT_VK_SUCCESS(err);
3911
3912     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3913     VkFramebuffer fb;
3914     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3915     ASSERT_VK_SUCCESS(err);
3916
3917     // Record a single command buffer which uses this renderpass twice. The
3918     // bug is triggered at the beginning of the second renderpass, when the
3919     // command buffer already has a layout recorded for the attachment.
3920     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3921     BeginCommandBuffer();
3922     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3923     vkCmdEndRenderPass(m_commandBuffer->handle());
3924     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3925
3926     m_errorMonitor->VerifyNotFound();
3927
3928     vkCmdEndRenderPass(m_commandBuffer->handle());
3929     EndCommandBuffer();
3930
3931     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3932     vkDestroyRenderPass(m_device->device(), rp, nullptr);
3933     vkDestroyImageView(m_device->device(), view, nullptr);
3934 }
3935
3936 TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
3937     TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
3938                      "command buffer, bind them together, then destroy "
3939                      "command pool and framebuffer and verify there are no "
3940                      "errors.");
3941
3942     m_errorMonitor->ExpectSuccess();
3943
3944     ASSERT_NO_FATAL_FAILURE(InitState());
3945
3946     // A renderpass with one color attachment.
3947     VkAttachmentDescription attachment = {0,
3948                                           VK_FORMAT_R8G8B8A8_UNORM,
3949                                           VK_SAMPLE_COUNT_1_BIT,
3950                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3951                                           VK_ATTACHMENT_STORE_OP_STORE,
3952                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3953                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3954                                           VK_IMAGE_LAYOUT_UNDEFINED,
3955                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3956
3957     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3958
3959     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3960
3961     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3962
3963     VkRenderPass rp;
3964     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3965     ASSERT_VK_SUCCESS(err);
3966
3967     // A compatible framebuffer.
3968     VkImageObj image(m_device);
3969     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3970     ASSERT_TRUE(image.initialized());
3971
3972     VkImageViewCreateInfo ivci = {
3973         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3974         nullptr,
3975         0,
3976         image.handle(),
3977         VK_IMAGE_VIEW_TYPE_2D,
3978         VK_FORMAT_R8G8B8A8_UNORM,
3979         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3980          VK_COMPONENT_SWIZZLE_IDENTITY},
3981         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3982     };
3983     VkImageView view;
3984     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3985     ASSERT_VK_SUCCESS(err);
3986
3987     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3988     VkFramebuffer fb;
3989     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3990     ASSERT_VK_SUCCESS(err);
3991
3992     // Explicitly create a command buffer to bind the FB to so that we can then
3993     //  destroy the command pool in order to implicitly free command buffer
3994     VkCommandPool command_pool;
3995     VkCommandPoolCreateInfo pool_create_info{};
3996     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3997     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3998     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3999     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4000
4001     VkCommandBuffer command_buffer;
4002     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4003     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4004     command_buffer_allocate_info.commandPool = command_pool;
4005     command_buffer_allocate_info.commandBufferCount = 1;
4006     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4007     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4008
4009     // Begin our cmd buffer with renderpass using our framebuffer
4010     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4011     VkCommandBufferBeginInfo begin_info{};
4012     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4013     vkBeginCommandBuffer(command_buffer, &begin_info);
4014
4015     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4016     vkCmdEndRenderPass(command_buffer);
4017     vkEndCommandBuffer(command_buffer);
4018     vkDestroyImageView(m_device->device(), view, nullptr);
4019     // Destroy command pool to implicitly free command buffer
4020     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4021     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4022     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4023     m_errorMonitor->VerifyNotFound();
4024 }
4025
4026 TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
4027     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
4028                      "transitions for the first subpass");
4029
4030     m_errorMonitor->ExpectSuccess();
4031
4032     ASSERT_NO_FATAL_FAILURE(InitState());
4033
4034     // A renderpass with one color attachment.
4035     VkAttachmentDescription attachment = {0,
4036                                           VK_FORMAT_R8G8B8A8_UNORM,
4037                                           VK_SAMPLE_COUNT_1_BIT,
4038                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4039                                           VK_ATTACHMENT_STORE_OP_STORE,
4040                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4041                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4042                                           VK_IMAGE_LAYOUT_UNDEFINED,
4043                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4044
4045     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4046
4047     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4048
4049     VkSubpassDependency dep = {0,
4050                                0,
4051                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4052                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4053                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4054                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4055                                VK_DEPENDENCY_BY_REGION_BIT};
4056
4057     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4058
4059     VkResult err;
4060     VkRenderPass rp;
4061     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4062     ASSERT_VK_SUCCESS(err);
4063
4064     // A compatible framebuffer.
4065     VkImageObj image(m_device);
4066     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4067     ASSERT_TRUE(image.initialized());
4068
4069     VkImageViewCreateInfo ivci = {
4070         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4071         nullptr,
4072         0,
4073         image.handle(),
4074         VK_IMAGE_VIEW_TYPE_2D,
4075         VK_FORMAT_R8G8B8A8_UNORM,
4076         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
4077          VK_COMPONENT_SWIZZLE_IDENTITY},
4078         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
4079     };
4080     VkImageView view;
4081     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4082     ASSERT_VK_SUCCESS(err);
4083
4084     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4085     VkFramebuffer fb;
4086     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4087     ASSERT_VK_SUCCESS(err);
4088
4089     // Record a single command buffer which issues a pipeline barrier w/
4090     // image memory barrier for the attachment. This detects the previously
4091     // missing tracking of the subpass layout by throwing a validation error
4092     // if it doesn't occur.
4093     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4094     BeginCommandBuffer();
4095     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4096
4097     VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4098                                 nullptr,
4099                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4100                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4101                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4102                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4103                                 VK_QUEUE_FAMILY_IGNORED,
4104                                 VK_QUEUE_FAMILY_IGNORED,
4105                                 image.handle(),
4106                                 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
4107     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4108                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4109                          &imb);
4110
4111     vkCmdEndRenderPass(m_commandBuffer->handle());
4112     m_errorMonitor->VerifyNotFound();
4113     EndCommandBuffer();
4114
4115     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4116     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4117     vkDestroyImageView(m_device->device(), view, nullptr);
4118 }
4119
4120 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
4121     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4122     ASSERT_NO_FATAL_FAILURE(InitState());
4123
4124     // A renderpass with two subpasses, both writing the same attachment.
4125     VkAttachmentDescription attach[] = {
4126         { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
4127             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4128             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4129             VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4130         },
4131     };
4132     VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
4133     VkSubpassDescription subpasses[] = {
4134         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4135             1, &ref, nullptr, nullptr, 0, nullptr },
4136         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4137             1, &ref, nullptr, nullptr, 0, nullptr },
4138     };
4139     VkSubpassDependency dep = {
4140         0, 1,
4141         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4142         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4143         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4144         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4145         VK_DEPENDENCY_BY_REGION_BIT
4146     };
4147     VkRenderPassCreateInfo rpci = {
4148         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
4149         0, 1, attach, 2, subpasses, 1, &dep
4150     };
4151     VkRenderPass rp;
4152     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4153     ASSERT_VK_SUCCESS(err);
4154
4155     VkImageObj image(m_device);
4156     image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
4157                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4158                          VK_IMAGE_TILING_OPTIMAL, 0);
4159     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4160
4161     VkFramebufferCreateInfo fbci = {
4162         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
4163         0, rp, 1, &imageView, 32, 32, 1
4164     };
4165     VkFramebuffer fb;
4166     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4167     ASSERT_VK_SUCCESS(err);
4168
4169     char const *vsSource =
4170         "#version 450\n"
4171         "void main() { gl_Position = vec4(1); }\n";
4172     char const *fsSource =
4173         "#version 450\n"
4174         "layout(location=0) out vec4 color;\n"
4175         "void main() { color = vec4(1); }\n";
4176
4177     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4178     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4179     VkPipelineObj pipe(m_device);
4180     pipe.AddColorAttachment();
4181     pipe.AddShader(&vs);
4182     pipe.AddShader(&fs);
4183     VkViewport view_port = {};
4184     m_viewports.push_back(view_port);
4185     pipe.SetViewport(m_viewports);
4186     VkRect2D rect = {};
4187     m_scissors.push_back(rect);
4188     pipe.SetScissor(m_scissors);
4189
4190     VkPipelineLayoutCreateInfo plci = {
4191         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
4192         0, 0, nullptr, 0, nullptr
4193     };
4194     VkPipelineLayout pl;
4195     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
4196     ASSERT_VK_SUCCESS(err);
4197     pipe.CreateVKPipeline(pl, rp);
4198
4199     BeginCommandBuffer();
4200
4201     VkRenderPassBeginInfo rpbi = {
4202         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
4203         rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
4204     };
4205
4206     // subtest 1: bind in the wrong subpass
4207     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4208     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4209     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4210                                          "built for subpass 0 but used in subpass 1");
4211     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4212     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4213     m_errorMonitor->VerifyFound();
4214
4215     vkCmdEndRenderPass(m_commandBuffer->handle());
4216
4217     // subtest 2: bind in correct subpass, then transition to next subpass
4218     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4219     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4220     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4222                                          "built for subpass 0 but used in subpass 1");
4223     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4224     m_errorMonitor->VerifyFound();
4225
4226     vkCmdEndRenderPass(m_commandBuffer->handle());
4227
4228     EndCommandBuffer();
4229
4230     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
4231     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4232     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4233 }
4234
4235 TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
4236     TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
4237                      "is used as a depth/stencil framebuffer attachment, the "
4238                      "aspectMask is ignored and both depth and stencil image "
4239                      "subresources are used.");
4240
4241     VkFormatProperties format_properties;
4242     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
4243     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
4244         return;
4245     }
4246
4247     m_errorMonitor->ExpectSuccess();
4248
4249     ASSERT_NO_FATAL_FAILURE(InitState());
4250
4251     VkAttachmentDescription attachment = {0,
4252                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
4253                                           VK_SAMPLE_COUNT_1_BIT,
4254                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4255                                           VK_ATTACHMENT_STORE_OP_STORE,
4256                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4257                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4258                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4259                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4260
4261     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4262
4263     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
4264
4265     VkSubpassDependency dep = {0,
4266                                0,
4267                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4268                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4269                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4270                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4271                                VK_DEPENDENCY_BY_REGION_BIT};
4272
4273     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4274
4275     VkResult err;
4276     VkRenderPass rp;
4277     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4278     ASSERT_VK_SUCCESS(err);
4279
4280     VkImageObj image(m_device);
4281     image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
4282                          0x26, // usage
4283                          VK_IMAGE_TILING_OPTIMAL, 0);
4284     ASSERT_TRUE(image.initialized());
4285     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
4286
4287     VkImageViewCreateInfo ivci = {
4288         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4289         nullptr,
4290         0,
4291         image.handle(),
4292         VK_IMAGE_VIEW_TYPE_2D,
4293         VK_FORMAT_D32_SFLOAT_S8_UINT,
4294         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
4295         {0x2, 0, 1, 0, 1},
4296     };
4297     VkImageView view;
4298     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4299     ASSERT_VK_SUCCESS(err);
4300
4301     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4302     VkFramebuffer fb;
4303     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4304     ASSERT_VK_SUCCESS(err);
4305
4306     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4307     BeginCommandBuffer();
4308     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4309
4310     VkImageMemoryBarrier imb = {};
4311     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4312     imb.pNext = nullptr;
4313     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4314     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4315     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4316     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4317     imb.srcQueueFamilyIndex = 0;
4318     imb.dstQueueFamilyIndex = 0;
4319     imb.image = image.handle();
4320     imb.subresourceRange.aspectMask = 0x6;
4321     imb.subresourceRange.baseMipLevel = 0;
4322     imb.subresourceRange.levelCount = 0x1;
4323     imb.subresourceRange.baseArrayLayer = 0;
4324     imb.subresourceRange.layerCount = 0x1;
4325
4326     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4327                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4328                          &imb);
4329
4330     vkCmdEndRenderPass(m_commandBuffer->handle());
4331     EndCommandBuffer();
4332     QueueCommandBuffer(false);
4333     m_errorMonitor->VerifyNotFound();
4334
4335     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4336     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4337     vkDestroyImageView(m_device->device(), view, nullptr);
4338 }
4339
4340 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
4341     TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass"
4342                      "with extent outside of framebuffer");
4343     ASSERT_NO_FATAL_FAILURE(InitState());
4344     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4345
4346     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea "
4347                                                                         "not within the bound of the framebuffer.");
4348
4349     // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
4350     m_renderPassBeginInfo.renderArea.extent.width = 257;
4351     m_renderPassBeginInfo.renderArea.extent.height = 257;
4352     BeginCommandBuffer();
4353     m_errorMonitor->VerifyFound();
4354 }
4355
4356 TEST_F(VkLayerTest, DisabledIndependentBlend) {
4357     TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent "
4358                      "blend and then specifying different blend states for two "
4359                      "attachements");
4360     VkPhysicalDeviceFeatures features = {};
4361     features.independentBlend = VK_FALSE;
4362     ASSERT_NO_FATAL_FAILURE(InitState(&features));
4363
4364     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4365                                          "Invalid Pipeline CreateInfo: If independent blend feature not "
4366                                          "enabled, all elements of pAttachments must be identical");
4367
4368     VkDescriptorSetObj descriptorSet(m_device);
4369     descriptorSet.AppendDummy();
4370     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4371
4372     VkPipelineObj pipeline(m_device);
4373     VkRenderpassObj renderpass(m_device);
4374     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4375     pipeline.AddShader(&vs);
4376
4377     VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
4378     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4379     att_state1.blendEnable = VK_TRUE;
4380     att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4381     att_state2.blendEnable = VK_FALSE;
4382     pipeline.AddColorAttachment(0, &att_state1);
4383     pipeline.AddColorAttachment(1, &att_state2);
4384     pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle());
4385     m_errorMonitor->VerifyFound();
4386 }
4387
4388 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) {
4389     TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify "
4390                      "depth attachments in subpass");
4391     ASSERT_NO_FATAL_FAILURE(InitState());
4392
4393     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4394                                          "vkCreateRenderPass has no depth/stencil attachment, yet subpass");
4395
4396     // Create a renderPass with a single color attachment
4397     VkAttachmentReference attach = {};
4398     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4399     VkSubpassDescription subpass = {};
4400     VkRenderPassCreateInfo rpci = {};
4401     rpci.subpassCount = 1;
4402     rpci.pSubpasses = &subpass;
4403     rpci.attachmentCount = 1;
4404     VkAttachmentDescription attach_desc = {};
4405     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4406     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4407     rpci.pAttachments = &attach_desc;
4408     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4409     VkRenderPass rp;
4410     subpass.pDepthStencilAttachment = &attach;
4411     subpass.pColorAttachments = NULL;
4412     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4413     m_errorMonitor->VerifyFound();
4414 }
4415
4416 TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
4417     TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
4418                      "errors, when an attachment reference is "
4419                      "VK_ATTACHMENT_UNUSED");
4420
4421     m_errorMonitor->ExpectSuccess();
4422
4423     ASSERT_NO_FATAL_FAILURE(InitState());
4424
4425     // A renderpass with no attachments
4426     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4427
4428     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4429
4430     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
4431
4432     VkRenderPass rp;
4433     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4434     ASSERT_VK_SUCCESS(err);
4435
4436     // A compatible framebuffer.
4437     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
4438     VkFramebuffer fb;
4439     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4440     ASSERT_VK_SUCCESS(err);
4441
4442     // Record a command buffer which just begins and ends the renderpass. The
4443     // bug manifests in BeginRenderPass.
4444     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4445     BeginCommandBuffer();
4446     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4447     vkCmdEndRenderPass(m_commandBuffer->handle());
4448     m_errorMonitor->VerifyNotFound();
4449     EndCommandBuffer();
4450
4451     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4452     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4453 }
4454
4455 // This is a positive test. No errors are expected.
4456 TEST_F(VkLayerTest, StencilLoadOp) {
4457     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
4458                      "CLEAR. stencil[Load|Store]Op used to be ignored.");
4459     VkResult result = VK_SUCCESS;
4460     VkImageFormatProperties formatProps;
4461     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
4462                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
4463                                              &formatProps);
4464     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
4465         return;
4466     }
4467
4468     ASSERT_NO_FATAL_FAILURE(InitState());
4469     VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
4470     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
4471                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4472     VkAttachmentDescription att = {};
4473     VkAttachmentReference ref = {};
4474     att.format = depth_stencil_fmt;
4475     att.samples = VK_SAMPLE_COUNT_1_BIT;
4476     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
4477     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
4478     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
4479     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
4480     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4481     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4482
4483     VkClearValue clear;
4484     clear.depthStencil.depth = 1.0;
4485     clear.depthStencil.stencil = 0;
4486     ref.attachment = 0;
4487     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4488
4489     VkSubpassDescription subpass = {};
4490     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4491     subpass.flags = 0;
4492     subpass.inputAttachmentCount = 0;
4493     subpass.pInputAttachments = NULL;
4494     subpass.colorAttachmentCount = 0;
4495     subpass.pColorAttachments = NULL;
4496     subpass.pResolveAttachments = NULL;
4497     subpass.pDepthStencilAttachment = &ref;
4498     subpass.preserveAttachmentCount = 0;
4499     subpass.pPreserveAttachments = NULL;
4500
4501     VkRenderPass rp;
4502     VkRenderPassCreateInfo rp_info = {};
4503     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4504     rp_info.attachmentCount = 1;
4505     rp_info.pAttachments = &att;
4506     rp_info.subpassCount = 1;
4507     rp_info.pSubpasses = &subpass;
4508     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
4509     ASSERT_VK_SUCCESS(result);
4510
4511     VkImageView *depthView = m_depthStencil->BindInfo();
4512     VkFramebufferCreateInfo fb_info = {};
4513     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4514     fb_info.pNext = NULL;
4515     fb_info.renderPass = rp;
4516     fb_info.attachmentCount = 1;
4517     fb_info.pAttachments = depthView;
4518     fb_info.width = 100;
4519     fb_info.height = 100;
4520     fb_info.layers = 1;
4521     VkFramebuffer fb;
4522     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4523     ASSERT_VK_SUCCESS(result);
4524
4525     VkRenderPassBeginInfo rpbinfo = {};
4526     rpbinfo.clearValueCount = 1;
4527     rpbinfo.pClearValues = &clear;
4528     rpbinfo.pNext = NULL;
4529     rpbinfo.renderPass = rp;
4530     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4531     rpbinfo.renderArea.extent.width = 100;
4532     rpbinfo.renderArea.extent.height = 100;
4533     rpbinfo.renderArea.offset.x = 0;
4534     rpbinfo.renderArea.offset.y = 0;
4535     rpbinfo.framebuffer = fb;
4536
4537     VkFence fence = {};
4538     VkFenceCreateInfo fence_ci = {};
4539     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4540     fence_ci.pNext = nullptr;
4541     fence_ci.flags = 0;
4542     result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
4543     ASSERT_VK_SUCCESS(result);
4544
4545     m_commandBuffer->BeginCommandBuffer();
4546     m_commandBuffer->BeginRenderPass(rpbinfo);
4547     m_commandBuffer->EndRenderPass();
4548     m_commandBuffer->EndCommandBuffer();
4549     m_commandBuffer->QueueCommandBuffer(fence);
4550
4551     VkImageObj destImage(m_device);
4552     destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4553                    VK_IMAGE_TILING_OPTIMAL, 0);
4554     VkImageMemoryBarrier barrier = {};
4555     VkImageSubresourceRange range;
4556     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4557     barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4558     barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4559     barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4560     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4561     barrier.image = m_depthStencil->handle();
4562     range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4563     range.baseMipLevel = 0;
4564     range.levelCount = 1;
4565     range.baseArrayLayer = 0;
4566     range.layerCount = 1;
4567     barrier.subresourceRange = range;
4568     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4569     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
4570     cmdbuf.BeginCommandBuffer();
4571     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4572                            &barrier);
4573     barrier.srcAccessMask = 0;
4574     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4575     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4576     barrier.image = destImage.handle();
4577     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4578     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4579                            &barrier);
4580     VkImageCopy cregion;
4581     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4582     cregion.srcSubresource.mipLevel = 0;
4583     cregion.srcSubresource.baseArrayLayer = 0;
4584     cregion.srcSubresource.layerCount = 1;
4585     cregion.srcOffset.x = 0;
4586     cregion.srcOffset.y = 0;
4587     cregion.srcOffset.z = 0;
4588     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4589     cregion.dstSubresource.mipLevel = 0;
4590     cregion.dstSubresource.baseArrayLayer = 0;
4591     cregion.dstSubresource.layerCount = 1;
4592     cregion.dstOffset.x = 0;
4593     cregion.dstOffset.y = 0;
4594     cregion.dstOffset.z = 0;
4595     cregion.extent.width = 100;
4596     cregion.extent.height = 100;
4597     cregion.extent.depth = 1;
4598     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
4599                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
4600     cmdbuf.EndCommandBuffer();
4601
4602     VkSubmitInfo submit_info;
4603     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4604     submit_info.pNext = NULL;
4605     submit_info.waitSemaphoreCount = 0;
4606     submit_info.pWaitSemaphores = NULL;
4607     submit_info.pWaitDstStageMask = NULL;
4608     submit_info.commandBufferCount = 1;
4609     submit_info.pCommandBuffers = &cmdbuf.handle();
4610     submit_info.signalSemaphoreCount = 0;
4611     submit_info.pSignalSemaphores = NULL;
4612
4613     m_errorMonitor->ExpectSuccess();
4614     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4615     m_errorMonitor->VerifyNotFound();
4616
4617     vkQueueWaitIdle(m_device->m_queue);
4618     vkDestroyFence(m_device->device(), fence, nullptr);
4619     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4620     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4621 }
4622
4623 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
4624     TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
4625                      "attachment reference of VK_ATTACHMENT_UNUSED");
4626
4627     ASSERT_NO_FATAL_FAILURE(InitState());
4628     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4629
4630     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED");
4631
4632     VkAttachmentReference color_attach = {};
4633     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4634     color_attach.attachment = 0;
4635     uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
4636     VkSubpassDescription subpass = {};
4637     subpass.colorAttachmentCount = 1;
4638     subpass.pColorAttachments = &color_attach;
4639     subpass.preserveAttachmentCount = 1;
4640     subpass.pPreserveAttachments = &preserve_attachment;
4641
4642     VkRenderPassCreateInfo rpci = {};
4643     rpci.subpassCount = 1;
4644     rpci.pSubpasses = &subpass;
4645     rpci.attachmentCount = 1;
4646     VkAttachmentDescription attach_desc = {};
4647     attach_desc.format = VK_FORMAT_UNDEFINED;
4648     rpci.pAttachments = &attach_desc;
4649     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4650     VkRenderPass rp;
4651     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4652
4653     m_errorMonitor->VerifyFound();
4654
4655     if (result == VK_SUCCESS) {
4656         vkDestroyRenderPass(m_device->device(), rp, NULL);
4657     }
4658 }
4659
4660 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
4661     TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
4662                      "when the source of a subpass multisample resolve "
4663                      "does not have multiple samples.");
4664
4665     ASSERT_NO_FATAL_FAILURE(InitState());
4666
4667     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4668                                          "Subpass 0 requests multisample resolve from attachment 0 which has "
4669                                          "VK_SAMPLE_COUNT_1_BIT");
4670
4671     VkAttachmentDescription attachments[] = {
4672         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4673          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4674          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4675         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4676          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4677          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4678     };
4679
4680     VkAttachmentReference color = {
4681         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4682     };
4683
4684     VkAttachmentReference resolve = {
4685         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4686     };
4687
4688     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4689
4690     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4691
4692     VkRenderPass rp;
4693     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4694
4695     m_errorMonitor->VerifyFound();
4696
4697     if (err == VK_SUCCESS)
4698         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4699 }
4700
4701 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
4702     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4703                      "when a subpass multisample resolve operation is "
4704                      "requested, and the destination of that resolve has "
4705                      "multiple samples.");
4706
4707     ASSERT_NO_FATAL_FAILURE(InitState());
4708
4709     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4710                                          "Subpass 0 requests multisample resolve into attachment 1, which "
4711                                          "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
4712
4713     VkAttachmentDescription attachments[] = {
4714         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4715          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4716          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4717         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4718          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4719          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4720     };
4721
4722     VkAttachmentReference color = {
4723         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4724     };
4725
4726     VkAttachmentReference resolve = {
4727         1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4728     };
4729
4730     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4731
4732     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4733
4734     VkRenderPass rp;
4735     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4736
4737     m_errorMonitor->VerifyFound();
4738
4739     if (err == VK_SUCCESS)
4740         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4741 }
4742
4743 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
4744     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4745                      "when the color and depth attachments used by a subpass "
4746                      "have inconsistent sample counts");
4747
4748     ASSERT_NO_FATAL_FAILURE(InitState());
4749
4750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4751                                          "Subpass 0 attempts to render to attachments with inconsistent sample counts");
4752
4753     VkAttachmentDescription attachments[] = {
4754         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4755          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4756          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4757         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4758          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4759          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4760     };
4761
4762     VkAttachmentReference color[] = {
4763         {
4764             0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4765         },
4766         {
4767             1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4768         },
4769     };
4770
4771     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr};
4772
4773     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4774
4775     VkRenderPass rp;
4776     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4777
4778     m_errorMonitor->VerifyFound();
4779
4780     if (err == VK_SUCCESS)
4781         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4782 }
4783
4784 TEST_F(VkLayerTest, FramebufferCreateErrors) {
4785     TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
4786                      " 1. Mismatch between fb & renderPass attachmentCount\n"
4787                      " 2. Use a color image as depthStencil attachment\n"
4788                      " 3. Mismatch fb & renderPass attachment formats\n"
4789                      " 4. Mismatch fb & renderPass attachment #samples\n"
4790                      " 5. FB attachment w/ non-1 mip-levels\n"
4791                      " 6. FB attachment where dimensions don't match\n"
4792                      " 7. FB attachment w/o identity swizzle\n"
4793                      " 8. FB dimensions exceed physical device limits\n");
4794
4795     ASSERT_NO_FATAL_FAILURE(InitState());
4796     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4797
4798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4799                                          "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
4800                                          "does not match attachmentCount of 1 of ");
4801
4802     // Create a renderPass with a single color attachment
4803     VkAttachmentReference attach = {};
4804     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4805     VkSubpassDescription subpass = {};
4806     subpass.pColorAttachments = &attach;
4807     VkRenderPassCreateInfo rpci = {};
4808     rpci.subpassCount = 1;
4809     rpci.pSubpasses = &subpass;
4810     rpci.attachmentCount = 1;
4811     VkAttachmentDescription attach_desc = {};
4812     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4813     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4814     rpci.pAttachments = &attach_desc;
4815     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4816     VkRenderPass rp;
4817     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4818     ASSERT_VK_SUCCESS(err);
4819
4820     VkImageView ivs[2];
4821     ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4822     ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4823     VkFramebufferCreateInfo fb_info = {};
4824     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4825     fb_info.pNext = NULL;
4826     fb_info.renderPass = rp;
4827     // Set mis-matching attachmentCount
4828     fb_info.attachmentCount = 2;
4829     fb_info.pAttachments = ivs;
4830     fb_info.width = 100;
4831     fb_info.height = 100;
4832     fb_info.layers = 1;
4833
4834     VkFramebuffer fb;
4835     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4836
4837     m_errorMonitor->VerifyFound();
4838     if (err == VK_SUCCESS) {
4839         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4840     }
4841     vkDestroyRenderPass(m_device->device(), rp, NULL);
4842
4843     // Create a renderPass with a depth-stencil attachment created with
4844     // IMAGE_USAGE_COLOR_ATTACHMENT
4845     // Add our color attachment to pDepthStencilAttachment
4846     subpass.pDepthStencilAttachment = &attach;
4847     subpass.pColorAttachments = NULL;
4848     VkRenderPass rp_ds;
4849     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
4850     ASSERT_VK_SUCCESS(err);
4851     // Set correct attachment count, but attachment has COLOR usage bit set
4852     fb_info.attachmentCount = 1;
4853     fb_info.renderPass = rp_ds;
4854
4855     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags ");
4856     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4857
4858     m_errorMonitor->VerifyFound();
4859     if (err == VK_SUCCESS) {
4860         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4861     }
4862     vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
4863
4864     // Create new renderpass with alternate attachment format from fb
4865     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
4866     subpass.pDepthStencilAttachment = NULL;
4867     subpass.pColorAttachments = &attach;
4868     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4869     ASSERT_VK_SUCCESS(err);
4870
4871     // Cause error due to mis-matched formats between rp & fb
4872     //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
4873     fb_info.renderPass = rp;
4874     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4875                                          " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
4876     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4877
4878     m_errorMonitor->VerifyFound();
4879     if (err == VK_SUCCESS) {
4880         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4881     }
4882     vkDestroyRenderPass(m_device->device(), rp, NULL);
4883
4884     // Create new renderpass with alternate sample count from fb
4885     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4886     attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
4887     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4888     ASSERT_VK_SUCCESS(err);
4889
4890     // Cause error due to mis-matched sample count between rp & fb
4891     fb_info.renderPass = rp;
4892     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples "
4893                                                                         "that do not match the "
4894                                                                         "VK_SAMPLE_COUNT_4_BIT ");
4895     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4896
4897     m_errorMonitor->VerifyFound();
4898     if (err == VK_SUCCESS) {
4899         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4900     }
4901
4902     vkDestroyRenderPass(m_device->device(), rp, NULL);
4903
4904     // Create a custom imageView with non-1 mip levels
4905     VkImageObj image(m_device);
4906     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4907     ASSERT_TRUE(image.initialized());
4908
4909     VkImageView view;
4910     VkImageViewCreateInfo ivci = {};
4911     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4912     ivci.image = image.handle();
4913     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4914     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4915     ivci.subresourceRange.layerCount = 1;
4916     ivci.subresourceRange.baseMipLevel = 0;
4917     // Set level count 2 (only 1 is allowed for FB attachment)
4918     ivci.subresourceRange.levelCount = 2;
4919     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4920     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4921     ASSERT_VK_SUCCESS(err);
4922     // Re-create renderpass to have matching sample count
4923     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4924     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4925     ASSERT_VK_SUCCESS(err);
4926
4927     fb_info.renderPass = rp;
4928     fb_info.pAttachments = &view;
4929     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only ");
4930     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4931
4932     m_errorMonitor->VerifyFound();
4933     if (err == VK_SUCCESS) {
4934         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4935     }
4936     vkDestroyImageView(m_device->device(), view, NULL);
4937     // Update view to original color buffer and grow FB dimensions too big
4938     fb_info.pAttachments = ivs;
4939     fb_info.height = 1024;
4940     fb_info.width = 1024;
4941     fb_info.layers = 2;
4942     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at "
4943                                                                         "least as large. ");
4944     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4945
4946     m_errorMonitor->VerifyFound();
4947     if (err == VK_SUCCESS) {
4948         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4949     }
4950     // Create view attachment with non-identity swizzle
4951     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4952     ivci.image = image.handle();
4953     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4954     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4955     ivci.subresourceRange.layerCount = 1;
4956     ivci.subresourceRange.baseMipLevel = 0;
4957     ivci.subresourceRange.levelCount = 1;
4958     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4959     ivci.components.r = VK_COMPONENT_SWIZZLE_G;
4960     ivci.components.g = VK_COMPONENT_SWIZZLE_R;
4961     ivci.components.b = VK_COMPONENT_SWIZZLE_A;
4962     ivci.components.a = VK_COMPONENT_SWIZZLE_B;
4963     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4964     ASSERT_VK_SUCCESS(err);
4965
4966     fb_info.pAttachments = &view;
4967     fb_info.height = 100;
4968     fb_info.width = 100;
4969     fb_info.layers = 1;
4970     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All "
4971                                                                         "framebuffer attachments must have "
4972                                                                         "been created with the identity "
4973                                                                         "swizzle. ");
4974     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4975
4976     m_errorMonitor->VerifyFound();
4977     if (err == VK_SUCCESS) {
4978         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4979     }
4980     vkDestroyImageView(m_device->device(), view, NULL);
4981     // Request fb that exceeds max dimensions
4982     // reset attachment to color attachment
4983     fb_info.pAttachments = ivs;
4984     fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
4985     fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
4986     fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
4987     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo "
4988                                                                         "dimensions exceed physical device "
4989                                                                         "limits. ");
4990     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4991
4992     m_errorMonitor->VerifyFound();
4993     if (err == VK_SUCCESS) {
4994         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4995     }
4996
4997     vkDestroyRenderPass(m_device->device(), rp, NULL);
4998 }
4999
5000 // This is a positive test.  No errors should be generated.
5001 TEST_F(VkLayerTest, WaitEventThenSet) {
5002     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
5003
5004     m_errorMonitor->ExpectSuccess();
5005     ASSERT_NO_FATAL_FAILURE(InitState());
5006
5007     VkEvent event;
5008     VkEventCreateInfo event_create_info{};
5009     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5010     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5011
5012     VkCommandPool command_pool;
5013     VkCommandPoolCreateInfo pool_create_info{};
5014     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5015     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5016     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5017     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5018
5019     VkCommandBuffer command_buffer;
5020     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5021     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5022     command_buffer_allocate_info.commandPool = command_pool;
5023     command_buffer_allocate_info.commandBufferCount = 1;
5024     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5025     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5026
5027     VkQueue queue = VK_NULL_HANDLE;
5028     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5029
5030     {
5031         VkCommandBufferBeginInfo begin_info{};
5032         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5033         vkBeginCommandBuffer(command_buffer, &begin_info);
5034
5035         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
5036                         nullptr, 0, nullptr);
5037         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5038         vkEndCommandBuffer(command_buffer);
5039     }
5040     {
5041         VkSubmitInfo submit_info{};
5042         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5043         submit_info.commandBufferCount = 1;
5044         submit_info.pCommandBuffers = &command_buffer;
5045         submit_info.signalSemaphoreCount = 0;
5046         submit_info.pSignalSemaphores = nullptr;
5047         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5048     }
5049     { vkSetEvent(m_device->device(), event); }
5050
5051     vkQueueWaitIdle(queue);
5052
5053     vkDestroyEvent(m_device->device(), event, nullptr);
5054     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5055     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5056
5057     m_errorMonitor->VerifyNotFound();
5058 }
5059 // This is a positive test.  No errors should be generated.
5060 TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
5061     TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
5062
5063     ASSERT_NO_FATAL_FAILURE(InitState());
5064     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5065         return;
5066
5067     m_errorMonitor->ExpectSuccess();
5068
5069     VkQueryPool query_pool;
5070     VkQueryPoolCreateInfo query_pool_create_info{};
5071     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5072     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5073     query_pool_create_info.queryCount = 1;
5074     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5075
5076     VkCommandPool command_pool;
5077     VkCommandPoolCreateInfo pool_create_info{};
5078     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5079     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5080     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5081     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5082
5083     VkCommandBuffer command_buffer;
5084     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5085     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5086     command_buffer_allocate_info.commandPool = command_pool;
5087     command_buffer_allocate_info.commandBufferCount = 1;
5088     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5089     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5090
5091     VkCommandBuffer secondary_command_buffer;
5092     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5093     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
5094
5095     VkQueue queue = VK_NULL_HANDLE;
5096     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5097
5098     uint32_t qfi = 0;
5099     VkBufferCreateInfo buff_create_info = {};
5100     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5101     buff_create_info.size = 1024;
5102     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5103     buff_create_info.queueFamilyIndexCount = 1;
5104     buff_create_info.pQueueFamilyIndices = &qfi;
5105
5106     VkResult err;
5107     VkBuffer buffer;
5108     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5109     ASSERT_VK_SUCCESS(err);
5110     VkMemoryAllocateInfo mem_alloc = {};
5111     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5112     mem_alloc.pNext = NULL;
5113     mem_alloc.allocationSize = 1024;
5114     mem_alloc.memoryTypeIndex = 0;
5115
5116     VkMemoryRequirements memReqs;
5117     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5118     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5119     if (!pass) {
5120         vkDestroyBuffer(m_device->device(), buffer, NULL);
5121         return;
5122     }
5123
5124     VkDeviceMemory mem;
5125     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5126     ASSERT_VK_SUCCESS(err);
5127     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5128     ASSERT_VK_SUCCESS(err);
5129
5130     VkCommandBufferInheritanceInfo hinfo = {};
5131     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5132     hinfo.renderPass = VK_NULL_HANDLE;
5133     hinfo.subpass = 0;
5134     hinfo.framebuffer = VK_NULL_HANDLE;
5135     hinfo.occlusionQueryEnable = VK_FALSE;
5136     hinfo.queryFlags = 0;
5137     hinfo.pipelineStatistics = 0;
5138
5139     {
5140         VkCommandBufferBeginInfo begin_info{};
5141         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5142         begin_info.pInheritanceInfo = &hinfo;
5143         vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
5144
5145         vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
5146         vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5147
5148         vkEndCommandBuffer(secondary_command_buffer);
5149
5150         begin_info.pInheritanceInfo = nullptr;
5151         vkBeginCommandBuffer(command_buffer, &begin_info);
5152
5153         vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
5154         vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
5155
5156         vkEndCommandBuffer(command_buffer);
5157     }
5158     {
5159         VkSubmitInfo submit_info{};
5160         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5161         submit_info.commandBufferCount = 1;
5162         submit_info.pCommandBuffers = &command_buffer;
5163         submit_info.signalSemaphoreCount = 0;
5164         submit_info.pSignalSemaphores = nullptr;
5165         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5166     }
5167
5168     vkQueueWaitIdle(queue);
5169
5170     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5171     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5172     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
5173     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5174     vkDestroyBuffer(m_device->device(), buffer, NULL);
5175     vkFreeMemory(m_device->device(), mem, NULL);
5176
5177     m_errorMonitor->VerifyNotFound();
5178 }
5179
5180 // This is a positive test.  No errors should be generated.
5181 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
5182     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
5183
5184     ASSERT_NO_FATAL_FAILURE(InitState());
5185     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5186         return;
5187
5188     m_errorMonitor->ExpectSuccess();
5189
5190     VkQueryPool query_pool;
5191     VkQueryPoolCreateInfo query_pool_create_info{};
5192     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5193     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5194     query_pool_create_info.queryCount = 1;
5195     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5196
5197     VkCommandPool command_pool;
5198     VkCommandPoolCreateInfo pool_create_info{};
5199     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5200     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5201     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5202     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5203
5204     VkCommandBuffer command_buffer[2];
5205     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5206     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5207     command_buffer_allocate_info.commandPool = command_pool;
5208     command_buffer_allocate_info.commandBufferCount = 2;
5209     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5210     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5211
5212     VkQueue queue = VK_NULL_HANDLE;
5213     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5214
5215     uint32_t qfi = 0;
5216     VkBufferCreateInfo buff_create_info = {};
5217     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5218     buff_create_info.size = 1024;
5219     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5220     buff_create_info.queueFamilyIndexCount = 1;
5221     buff_create_info.pQueueFamilyIndices = &qfi;
5222
5223     VkResult err;
5224     VkBuffer buffer;
5225     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5226     ASSERT_VK_SUCCESS(err);
5227     VkMemoryAllocateInfo mem_alloc = {};
5228     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5229     mem_alloc.pNext = NULL;
5230     mem_alloc.allocationSize = 1024;
5231     mem_alloc.memoryTypeIndex = 0;
5232
5233     VkMemoryRequirements memReqs;
5234     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5235     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5236     if (!pass) {
5237         vkDestroyBuffer(m_device->device(), buffer, NULL);
5238         return;
5239     }
5240
5241     VkDeviceMemory mem;
5242     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5243     ASSERT_VK_SUCCESS(err);
5244     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5245     ASSERT_VK_SUCCESS(err);
5246
5247     {
5248         VkCommandBufferBeginInfo begin_info{};
5249         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5250         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5251
5252         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
5253         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5254
5255         vkEndCommandBuffer(command_buffer[0]);
5256
5257         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5258
5259         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
5260
5261         vkEndCommandBuffer(command_buffer[1]);
5262     }
5263     {
5264         VkSubmitInfo submit_info{};
5265         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5266         submit_info.commandBufferCount = 2;
5267         submit_info.pCommandBuffers = command_buffer;
5268         submit_info.signalSemaphoreCount = 0;
5269         submit_info.pSignalSemaphores = nullptr;
5270         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5271     }
5272
5273     vkQueueWaitIdle(queue);
5274
5275     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5276     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
5277     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5278     vkDestroyBuffer(m_device->device(), buffer, NULL);
5279     vkFreeMemory(m_device->device(), mem, NULL);
5280
5281     m_errorMonitor->VerifyNotFound();
5282 }
5283
5284 TEST_F(VkLayerTest, ResetEventThenSet) {
5285     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
5286
5287     m_errorMonitor->ExpectSuccess();
5288
5289     ASSERT_NO_FATAL_FAILURE(InitState());
5290     VkEvent event;
5291     VkEventCreateInfo event_create_info{};
5292     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5293     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5294
5295     VkCommandPool command_pool;
5296     VkCommandPoolCreateInfo pool_create_info{};
5297     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5298     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5299     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5300     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5301
5302     VkCommandBuffer command_buffer;
5303     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5304     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5305     command_buffer_allocate_info.commandPool = command_pool;
5306     command_buffer_allocate_info.commandBufferCount = 1;
5307     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5308     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5309
5310     VkQueue queue = VK_NULL_HANDLE;
5311     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5312
5313     {
5314         VkCommandBufferBeginInfo begin_info{};
5315         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5316         vkBeginCommandBuffer(command_buffer, &begin_info);
5317
5318         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5319         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
5320                         nullptr, 0, nullptr, 0, nullptr);
5321         vkEndCommandBuffer(command_buffer);
5322     }
5323     {
5324         VkSubmitInfo submit_info{};
5325         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5326         submit_info.commandBufferCount = 1;
5327         submit_info.pCommandBuffers = &command_buffer;
5328         submit_info.signalSemaphoreCount = 0;
5329         submit_info.pSignalSemaphores = nullptr;
5330         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5331     }
5332     {
5333         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
5334                                                                             "command buffer.");
5335         vkSetEvent(m_device->device(), event);
5336         m_errorMonitor->VerifyFound();
5337     }
5338
5339     vkQueueWaitIdle(queue);
5340
5341     vkDestroyEvent(m_device->device(), event, nullptr);
5342     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5343     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5344 }
5345
5346 // This is a positive test.  No errors should be generated.
5347 TEST_F(VkLayerTest, TwoFencesThreeFrames) {
5348     TEST_DESCRIPTION("Two command buffers with two separate fences are each "
5349                      "run through a Submit & WaitForFences cycle 3 times. This "
5350                      "previously revealed a bug so running this positive test "
5351                      "to prevent a regression.");
5352     m_errorMonitor->ExpectSuccess();
5353
5354     ASSERT_NO_FATAL_FAILURE(InitState());
5355     VkQueue queue = VK_NULL_HANDLE;
5356     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5357
5358     static const uint32_t NUM_OBJECTS = 2;
5359     static const uint32_t NUM_FRAMES = 3;
5360     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
5361     VkFence fences[NUM_OBJECTS] = {};
5362
5363     VkCommandPool cmd_pool;
5364     VkCommandPoolCreateInfo cmd_pool_ci = {};
5365     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5366     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
5367     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5368     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
5369     ASSERT_VK_SUCCESS(err);
5370
5371     VkCommandBufferAllocateInfo cmd_buf_info = {};
5372     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5373     cmd_buf_info.commandPool = cmd_pool;
5374     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5375     cmd_buf_info.commandBufferCount = 1;
5376
5377     VkFenceCreateInfo fence_ci = {};
5378     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5379     fence_ci.pNext = nullptr;
5380     fence_ci.flags = 0;
5381
5382     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5383         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
5384         ASSERT_VK_SUCCESS(err);
5385         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
5386         ASSERT_VK_SUCCESS(err);
5387     }
5388
5389     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
5390         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
5391             // Create empty cmd buffer
5392             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
5393             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5394
5395             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
5396             ASSERT_VK_SUCCESS(err);
5397             err = vkEndCommandBuffer(cmd_buffers[obj]);
5398             ASSERT_VK_SUCCESS(err);
5399
5400             VkSubmitInfo submit_info = {};
5401             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5402             submit_info.commandBufferCount = 1;
5403             submit_info.pCommandBuffers = &cmd_buffers[obj];
5404             // Submit cmd buffer and wait for fence
5405             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
5406             ASSERT_VK_SUCCESS(err);
5407             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
5408             ASSERT_VK_SUCCESS(err);
5409             err = vkResetFences(m_device->device(), 1, &fences[obj]);
5410             ASSERT_VK_SUCCESS(err);
5411         }
5412     }
5413     m_errorMonitor->VerifyNotFound();
5414     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
5415     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5416         vkDestroyFence(m_device->device(), fences[i], nullptr);
5417     }
5418 }
5419 // This is a positive test.  No errors should be generated.
5420 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
5421
5422     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5423                      "submitted on separate queues followed by a QueueWaitIdle.");
5424
5425     ASSERT_NO_FATAL_FAILURE(InitState());
5426     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5427         return;
5428
5429     m_errorMonitor->ExpectSuccess();
5430
5431     VkSemaphore semaphore;
5432     VkSemaphoreCreateInfo semaphore_create_info{};
5433     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5434     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5435
5436     VkCommandPool command_pool;
5437     VkCommandPoolCreateInfo pool_create_info{};
5438     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5439     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5440     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5441     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5442
5443     VkCommandBuffer command_buffer[2];
5444     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5445     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5446     command_buffer_allocate_info.commandPool = command_pool;
5447     command_buffer_allocate_info.commandBufferCount = 2;
5448     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5449     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5450
5451     VkQueue queue = VK_NULL_HANDLE;
5452     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5453
5454     {
5455         VkCommandBufferBeginInfo begin_info{};
5456         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5457         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5458
5459         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5460                              nullptr, 0, nullptr, 0, nullptr);
5461
5462         VkViewport viewport{};
5463         viewport.maxDepth = 1.0f;
5464         viewport.minDepth = 0.0f;
5465         viewport.width = 512;
5466         viewport.height = 512;
5467         viewport.x = 0;
5468         viewport.y = 0;
5469         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5470         vkEndCommandBuffer(command_buffer[0]);
5471     }
5472     {
5473         VkCommandBufferBeginInfo begin_info{};
5474         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5475         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5476
5477         VkViewport viewport{};
5478         viewport.maxDepth = 1.0f;
5479         viewport.minDepth = 0.0f;
5480         viewport.width = 512;
5481         viewport.height = 512;
5482         viewport.x = 0;
5483         viewport.y = 0;
5484         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5485         vkEndCommandBuffer(command_buffer[1]);
5486     }
5487     {
5488         VkSubmitInfo submit_info{};
5489         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5490         submit_info.commandBufferCount = 1;
5491         submit_info.pCommandBuffers = &command_buffer[0];
5492         submit_info.signalSemaphoreCount = 1;
5493         submit_info.pSignalSemaphores = &semaphore;
5494         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5495     }
5496     {
5497         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5498         VkSubmitInfo submit_info{};
5499         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5500         submit_info.commandBufferCount = 1;
5501         submit_info.pCommandBuffers = &command_buffer[1];
5502         submit_info.waitSemaphoreCount = 1;
5503         submit_info.pWaitSemaphores = &semaphore;
5504         submit_info.pWaitDstStageMask = flags;
5505         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5506     }
5507
5508     vkQueueWaitIdle(m_device->m_queue);
5509
5510     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5511     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5512     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5513
5514     m_errorMonitor->VerifyNotFound();
5515 }
5516
5517 // This is a positive test.  No errors should be generated.
5518 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
5519
5520     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5521                      "submitted on separate queues, the second having a fence"
5522                      "followed by a QueueWaitIdle.");
5523
5524     ASSERT_NO_FATAL_FAILURE(InitState());
5525     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5526         return;
5527
5528     m_errorMonitor->ExpectSuccess();
5529
5530     VkFence fence;
5531     VkFenceCreateInfo fence_create_info{};
5532     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5533     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5534
5535     VkSemaphore semaphore;
5536     VkSemaphoreCreateInfo semaphore_create_info{};
5537     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5538     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5539
5540     VkCommandPool command_pool;
5541     VkCommandPoolCreateInfo pool_create_info{};
5542     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5543     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5544     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5545     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5546
5547     VkCommandBuffer command_buffer[2];
5548     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5549     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5550     command_buffer_allocate_info.commandPool = command_pool;
5551     command_buffer_allocate_info.commandBufferCount = 2;
5552     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5553     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5554
5555     VkQueue queue = VK_NULL_HANDLE;
5556     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5557
5558     {
5559         VkCommandBufferBeginInfo begin_info{};
5560         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5561         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5562
5563         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5564                              nullptr, 0, nullptr, 0, nullptr);
5565
5566         VkViewport viewport{};
5567         viewport.maxDepth = 1.0f;
5568         viewport.minDepth = 0.0f;
5569         viewport.width = 512;
5570         viewport.height = 512;
5571         viewport.x = 0;
5572         viewport.y = 0;
5573         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5574         vkEndCommandBuffer(command_buffer[0]);
5575     }
5576     {
5577         VkCommandBufferBeginInfo begin_info{};
5578         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5579         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5580
5581         VkViewport viewport{};
5582         viewport.maxDepth = 1.0f;
5583         viewport.minDepth = 0.0f;
5584         viewport.width = 512;
5585         viewport.height = 512;
5586         viewport.x = 0;
5587         viewport.y = 0;
5588         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5589         vkEndCommandBuffer(command_buffer[1]);
5590     }
5591     {
5592         VkSubmitInfo submit_info{};
5593         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5594         submit_info.commandBufferCount = 1;
5595         submit_info.pCommandBuffers = &command_buffer[0];
5596         submit_info.signalSemaphoreCount = 1;
5597         submit_info.pSignalSemaphores = &semaphore;
5598         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5599     }
5600     {
5601         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5602         VkSubmitInfo submit_info{};
5603         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5604         submit_info.commandBufferCount = 1;
5605         submit_info.pCommandBuffers = &command_buffer[1];
5606         submit_info.waitSemaphoreCount = 1;
5607         submit_info.pWaitSemaphores = &semaphore;
5608         submit_info.pWaitDstStageMask = flags;
5609         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5610     }
5611
5612     vkQueueWaitIdle(m_device->m_queue);
5613
5614     vkDestroyFence(m_device->device(), fence, nullptr);
5615     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5616     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5617     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5618
5619     m_errorMonitor->VerifyNotFound();
5620 }
5621
5622 // This is a positive test.  No errors should be generated.
5623 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
5624
5625     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5626                      "submitted on separate queues, the second having a fence"
5627                      "followed by two consecutive WaitForFences calls on the same fence.");
5628
5629     ASSERT_NO_FATAL_FAILURE(InitState());
5630     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5631         return;
5632
5633     m_errorMonitor->ExpectSuccess();
5634
5635     VkFence fence;
5636     VkFenceCreateInfo fence_create_info{};
5637     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5638     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5639
5640     VkSemaphore semaphore;
5641     VkSemaphoreCreateInfo semaphore_create_info{};
5642     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5643     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5644
5645     VkCommandPool command_pool;
5646     VkCommandPoolCreateInfo pool_create_info{};
5647     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5648     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5649     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5650     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5651
5652     VkCommandBuffer command_buffer[2];
5653     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5654     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5655     command_buffer_allocate_info.commandPool = command_pool;
5656     command_buffer_allocate_info.commandBufferCount = 2;
5657     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5658     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5659
5660     VkQueue queue = VK_NULL_HANDLE;
5661     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5662
5663     {
5664         VkCommandBufferBeginInfo begin_info{};
5665         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5666         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5667
5668         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5669                              nullptr, 0, nullptr, 0, nullptr);
5670
5671         VkViewport viewport{};
5672         viewport.maxDepth = 1.0f;
5673         viewport.minDepth = 0.0f;
5674         viewport.width = 512;
5675         viewport.height = 512;
5676         viewport.x = 0;
5677         viewport.y = 0;
5678         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5679         vkEndCommandBuffer(command_buffer[0]);
5680     }
5681     {
5682         VkCommandBufferBeginInfo begin_info{};
5683         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5684         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5685
5686         VkViewport viewport{};
5687         viewport.maxDepth = 1.0f;
5688         viewport.minDepth = 0.0f;
5689         viewport.width = 512;
5690         viewport.height = 512;
5691         viewport.x = 0;
5692         viewport.y = 0;
5693         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5694         vkEndCommandBuffer(command_buffer[1]);
5695     }
5696     {
5697         VkSubmitInfo submit_info{};
5698         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5699         submit_info.commandBufferCount = 1;
5700         submit_info.pCommandBuffers = &command_buffer[0];
5701         submit_info.signalSemaphoreCount = 1;
5702         submit_info.pSignalSemaphores = &semaphore;
5703         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5704     }
5705     {
5706         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5707         VkSubmitInfo submit_info{};
5708         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5709         submit_info.commandBufferCount = 1;
5710         submit_info.pCommandBuffers = &command_buffer[1];
5711         submit_info.waitSemaphoreCount = 1;
5712         submit_info.pWaitSemaphores = &semaphore;
5713         submit_info.pWaitDstStageMask = flags;
5714         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5715     }
5716
5717     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5718     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5719
5720     vkDestroyFence(m_device->device(), fence, nullptr);
5721     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5722     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5723     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5724
5725     m_errorMonitor->VerifyNotFound();
5726 }
5727
5728 TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
5729
5730     ASSERT_NO_FATAL_FAILURE(InitState());
5731     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
5732         printf("Test requires two queues, skipping\n");
5733         return;
5734     }
5735
5736     VkResult err;
5737
5738     m_errorMonitor->ExpectSuccess();
5739
5740     VkQueue q0 = m_device->m_queue;
5741     VkQueue q1 = nullptr;
5742     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
5743     ASSERT_NE(q1, nullptr);
5744
5745     // An (empty) command buffer. We must have work in the first submission --
5746     // the layer treats unfenced work differently from fenced work.
5747     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
5748     VkCommandPool pool;
5749     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
5750     ASSERT_VK_SUCCESS(err);
5751     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
5752                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
5753     VkCommandBuffer cb;
5754     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
5755     ASSERT_VK_SUCCESS(err);
5756     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
5757     err = vkBeginCommandBuffer(cb, &cbbi);
5758     ASSERT_VK_SUCCESS(err);
5759     err = vkEndCommandBuffer(cb);
5760     ASSERT_VK_SUCCESS(err);
5761
5762     // A semaphore
5763     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5764     VkSemaphore s;
5765     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
5766     ASSERT_VK_SUCCESS(err);
5767
5768     // First submission, to q0
5769     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
5770
5771     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
5772     ASSERT_VK_SUCCESS(err);
5773
5774     // Second submission, to q1, waiting on s
5775     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
5776     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
5777
5778     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
5779     ASSERT_VK_SUCCESS(err);
5780
5781     // Wait for q0 idle
5782     err = vkQueueWaitIdle(q0);
5783     ASSERT_VK_SUCCESS(err);
5784
5785     // Command buffer should have been completed (it was on q0); reset the pool.
5786     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
5787
5788     m_errorMonitor->VerifyNotFound();
5789
5790     // Force device completely idle and clean up resources
5791     vkDeviceWaitIdle(m_device->device());
5792     vkDestroyCommandPool(m_device->device(), pool, nullptr);
5793     vkDestroySemaphore(m_device->device(), s, nullptr);
5794 }
5795
5796 // This is a positive test.  No errors should be generated.
5797 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
5798
5799     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5800                      "submitted on separate queues, the second having a fence, "
5801                      "followed by a WaitForFences call.");
5802
5803     ASSERT_NO_FATAL_FAILURE(InitState());
5804     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5805         return;
5806
5807     m_errorMonitor->ExpectSuccess();
5808
5809     ASSERT_NO_FATAL_FAILURE(InitState());
5810     VkFence fence;
5811     VkFenceCreateInfo fence_create_info{};
5812     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5813     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5814
5815     VkSemaphore semaphore;
5816     VkSemaphoreCreateInfo semaphore_create_info{};
5817     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5818     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5819
5820     VkCommandPool command_pool;
5821     VkCommandPoolCreateInfo pool_create_info{};
5822     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5823     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5824     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5825     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5826
5827     VkCommandBuffer command_buffer[2];
5828     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5829     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5830     command_buffer_allocate_info.commandPool = command_pool;
5831     command_buffer_allocate_info.commandBufferCount = 2;
5832     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5833     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5834
5835     VkQueue queue = VK_NULL_HANDLE;
5836     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5837
5838     {
5839         VkCommandBufferBeginInfo begin_info{};
5840         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5841         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5842
5843         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5844                              nullptr, 0, nullptr, 0, nullptr);
5845
5846         VkViewport viewport{};
5847         viewport.maxDepth = 1.0f;
5848         viewport.minDepth = 0.0f;
5849         viewport.width = 512;
5850         viewport.height = 512;
5851         viewport.x = 0;
5852         viewport.y = 0;
5853         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5854         vkEndCommandBuffer(command_buffer[0]);
5855     }
5856     {
5857         VkCommandBufferBeginInfo begin_info{};
5858         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5859         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5860
5861         VkViewport viewport{};
5862         viewport.maxDepth = 1.0f;
5863         viewport.minDepth = 0.0f;
5864         viewport.width = 512;
5865         viewport.height = 512;
5866         viewport.x = 0;
5867         viewport.y = 0;
5868         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5869         vkEndCommandBuffer(command_buffer[1]);
5870     }
5871     {
5872         VkSubmitInfo submit_info{};
5873         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5874         submit_info.commandBufferCount = 1;
5875         submit_info.pCommandBuffers = &command_buffer[0];
5876         submit_info.signalSemaphoreCount = 1;
5877         submit_info.pSignalSemaphores = &semaphore;
5878         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5879     }
5880     {
5881         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5882         VkSubmitInfo submit_info{};
5883         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5884         submit_info.commandBufferCount = 1;
5885         submit_info.pCommandBuffers = &command_buffer[1];
5886         submit_info.waitSemaphoreCount = 1;
5887         submit_info.pWaitSemaphores = &semaphore;
5888         submit_info.pWaitDstStageMask = flags;
5889         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5890     }
5891
5892     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5893
5894     vkDestroyFence(m_device->device(), fence, nullptr);
5895     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5896     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5897     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5898
5899     m_errorMonitor->VerifyNotFound();
5900 }
5901
5902 // This is a positive test.  No errors should be generated.
5903 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
5904
5905     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5906                      "on the same queue, sharing a signal/wait semaphore, the "
5907                      "second having a fence, "
5908                      "followed by a WaitForFences call.");
5909
5910     m_errorMonitor->ExpectSuccess();
5911
5912     ASSERT_NO_FATAL_FAILURE(InitState());
5913     VkFence fence;
5914     VkFenceCreateInfo fence_create_info{};
5915     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5916     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5917
5918     VkSemaphore semaphore;
5919     VkSemaphoreCreateInfo semaphore_create_info{};
5920     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5921     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5922
5923     VkCommandPool command_pool;
5924     VkCommandPoolCreateInfo pool_create_info{};
5925     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5926     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5927     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5928     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5929
5930     VkCommandBuffer command_buffer[2];
5931     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5932     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5933     command_buffer_allocate_info.commandPool = command_pool;
5934     command_buffer_allocate_info.commandBufferCount = 2;
5935     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5936     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5937
5938     {
5939         VkCommandBufferBeginInfo begin_info{};
5940         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5941         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5942
5943         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5944                              nullptr, 0, nullptr, 0, nullptr);
5945
5946         VkViewport viewport{};
5947         viewport.maxDepth = 1.0f;
5948         viewport.minDepth = 0.0f;
5949         viewport.width = 512;
5950         viewport.height = 512;
5951         viewport.x = 0;
5952         viewport.y = 0;
5953         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5954         vkEndCommandBuffer(command_buffer[0]);
5955     }
5956     {
5957         VkCommandBufferBeginInfo begin_info{};
5958         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5959         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5960
5961         VkViewport viewport{};
5962         viewport.maxDepth = 1.0f;
5963         viewport.minDepth = 0.0f;
5964         viewport.width = 512;
5965         viewport.height = 512;
5966         viewport.x = 0;
5967         viewport.y = 0;
5968         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5969         vkEndCommandBuffer(command_buffer[1]);
5970     }
5971     {
5972         VkSubmitInfo submit_info{};
5973         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5974         submit_info.commandBufferCount = 1;
5975         submit_info.pCommandBuffers = &command_buffer[0];
5976         submit_info.signalSemaphoreCount = 1;
5977         submit_info.pSignalSemaphores = &semaphore;
5978         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5979     }
5980     {
5981         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5982         VkSubmitInfo submit_info{};
5983         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5984         submit_info.commandBufferCount = 1;
5985         submit_info.pCommandBuffers = &command_buffer[1];
5986         submit_info.waitSemaphoreCount = 1;
5987         submit_info.pWaitSemaphores = &semaphore;
5988         submit_info.pWaitDstStageMask = flags;
5989         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5990     }
5991
5992     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5993
5994     vkDestroyFence(m_device->device(), fence, nullptr);
5995     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5996     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5997     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5998
5999     m_errorMonitor->VerifyNotFound();
6000 }
6001
6002 // This is a positive test.  No errors should be generated.
6003 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
6004
6005     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6006                      "on the same queue, no fences, followed by a third QueueSubmit with NO "
6007                      "SubmitInfos but with a fence, followed by a WaitForFences call.");
6008
6009     m_errorMonitor->ExpectSuccess();
6010
6011     ASSERT_NO_FATAL_FAILURE(InitState());
6012     VkFence fence;
6013     VkFenceCreateInfo fence_create_info{};
6014     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6015     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6016
6017     VkCommandPool command_pool;
6018     VkCommandPoolCreateInfo pool_create_info{};
6019     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6020     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6021     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6022     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6023
6024     VkCommandBuffer command_buffer[2];
6025     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6026     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6027     command_buffer_allocate_info.commandPool = command_pool;
6028     command_buffer_allocate_info.commandBufferCount = 2;
6029     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6030     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6031
6032     {
6033         VkCommandBufferBeginInfo begin_info{};
6034         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6035         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6036
6037         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6038                              nullptr, 0, nullptr, 0, nullptr);
6039
6040         VkViewport viewport{};
6041         viewport.maxDepth = 1.0f;
6042         viewport.minDepth = 0.0f;
6043         viewport.width = 512;
6044         viewport.height = 512;
6045         viewport.x = 0;
6046         viewport.y = 0;
6047         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6048         vkEndCommandBuffer(command_buffer[0]);
6049     }
6050     {
6051         VkCommandBufferBeginInfo begin_info{};
6052         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6053         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6054
6055         VkViewport viewport{};
6056         viewport.maxDepth = 1.0f;
6057         viewport.minDepth = 0.0f;
6058         viewport.width = 512;
6059         viewport.height = 512;
6060         viewport.x = 0;
6061         viewport.y = 0;
6062         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6063         vkEndCommandBuffer(command_buffer[1]);
6064     }
6065     {
6066         VkSubmitInfo submit_info{};
6067         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6068         submit_info.commandBufferCount = 1;
6069         submit_info.pCommandBuffers = &command_buffer[0];
6070         submit_info.signalSemaphoreCount = 0;
6071         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6072         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6073     }
6074     {
6075         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6076         VkSubmitInfo submit_info{};
6077         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6078         submit_info.commandBufferCount = 1;
6079         submit_info.pCommandBuffers = &command_buffer[1];
6080         submit_info.waitSemaphoreCount = 0;
6081         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6082         submit_info.pWaitDstStageMask = flags;
6083         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6084     }
6085
6086     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
6087
6088     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6089     ASSERT_VK_SUCCESS(err);
6090
6091     vkDestroyFence(m_device->device(), fence, nullptr);
6092     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6093     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6094
6095     m_errorMonitor->VerifyNotFound();
6096 }
6097
6098 // This is a positive test.  No errors should be generated.
6099 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
6100
6101     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6102                      "on the same queue, the second having a fence, followed "
6103                      "by a WaitForFences call.");
6104
6105     m_errorMonitor->ExpectSuccess();
6106
6107     ASSERT_NO_FATAL_FAILURE(InitState());
6108     VkFence fence;
6109     VkFenceCreateInfo fence_create_info{};
6110     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6111     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6112
6113     VkCommandPool command_pool;
6114     VkCommandPoolCreateInfo pool_create_info{};
6115     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6116     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6117     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6118     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6119
6120     VkCommandBuffer command_buffer[2];
6121     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6122     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6123     command_buffer_allocate_info.commandPool = command_pool;
6124     command_buffer_allocate_info.commandBufferCount = 2;
6125     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6126     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6127
6128     {
6129         VkCommandBufferBeginInfo begin_info{};
6130         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6131         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6132
6133         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6134                              nullptr, 0, nullptr, 0, nullptr);
6135
6136         VkViewport viewport{};
6137         viewport.maxDepth = 1.0f;
6138         viewport.minDepth = 0.0f;
6139         viewport.width = 512;
6140         viewport.height = 512;
6141         viewport.x = 0;
6142         viewport.y = 0;
6143         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6144         vkEndCommandBuffer(command_buffer[0]);
6145     }
6146     {
6147         VkCommandBufferBeginInfo begin_info{};
6148         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6149         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6150
6151         VkViewport viewport{};
6152         viewport.maxDepth = 1.0f;
6153         viewport.minDepth = 0.0f;
6154         viewport.width = 512;
6155         viewport.height = 512;
6156         viewport.x = 0;
6157         viewport.y = 0;
6158         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6159         vkEndCommandBuffer(command_buffer[1]);
6160     }
6161     {
6162         VkSubmitInfo submit_info{};
6163         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6164         submit_info.commandBufferCount = 1;
6165         submit_info.pCommandBuffers = &command_buffer[0];
6166         submit_info.signalSemaphoreCount = 0;
6167         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6168         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6169     }
6170     {
6171         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6172         VkSubmitInfo submit_info{};
6173         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6174         submit_info.commandBufferCount = 1;
6175         submit_info.pCommandBuffers = &command_buffer[1];
6176         submit_info.waitSemaphoreCount = 0;
6177         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6178         submit_info.pWaitDstStageMask = flags;
6179         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
6180     }
6181
6182     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6183
6184     vkDestroyFence(m_device->device(), fence, nullptr);
6185     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6186     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6187
6188     m_errorMonitor->VerifyNotFound();
6189 }
6190
6191 // This is a positive test.  No errors should be generated.
6192 TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
6193
6194     TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
6195                      "QueueSubmit call followed by a WaitForFences call.");
6196     ASSERT_NO_FATAL_FAILURE(InitState());
6197
6198     m_errorMonitor->ExpectSuccess();
6199
6200     VkFence fence;
6201     VkFenceCreateInfo fence_create_info{};
6202     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6203     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6204
6205     VkSemaphore semaphore;
6206     VkSemaphoreCreateInfo semaphore_create_info{};
6207     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6208     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
6209
6210     VkCommandPool command_pool;
6211     VkCommandPoolCreateInfo pool_create_info{};
6212     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6213     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6214     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6215     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6216
6217     VkCommandBuffer command_buffer[2];
6218     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6219     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6220     command_buffer_allocate_info.commandPool = command_pool;
6221     command_buffer_allocate_info.commandBufferCount = 2;
6222     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6223     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6224
6225     {
6226         VkCommandBufferBeginInfo begin_info{};
6227         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6228         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6229
6230         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6231                              nullptr, 0, nullptr, 0, nullptr);
6232
6233         VkViewport viewport{};
6234         viewport.maxDepth = 1.0f;
6235         viewport.minDepth = 0.0f;
6236         viewport.width = 512;
6237         viewport.height = 512;
6238         viewport.x = 0;
6239         viewport.y = 0;
6240         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6241         vkEndCommandBuffer(command_buffer[0]);
6242     }
6243     {
6244         VkCommandBufferBeginInfo begin_info{};
6245         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6246         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6247
6248         VkViewport viewport{};
6249         viewport.maxDepth = 1.0f;
6250         viewport.minDepth = 0.0f;
6251         viewport.width = 512;
6252         viewport.height = 512;
6253         viewport.x = 0;
6254         viewport.y = 0;
6255         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6256         vkEndCommandBuffer(command_buffer[1]);
6257     }
6258     {
6259         VkSubmitInfo submit_info[2];
6260         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6261
6262         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6263         submit_info[0].pNext = NULL;
6264         submit_info[0].commandBufferCount = 1;
6265         submit_info[0].pCommandBuffers = &command_buffer[0];
6266         submit_info[0].signalSemaphoreCount = 1;
6267         submit_info[0].pSignalSemaphores = &semaphore;
6268         submit_info[0].waitSemaphoreCount = 0;
6269         submit_info[0].pWaitSemaphores = NULL;
6270         submit_info[0].pWaitDstStageMask = 0;
6271
6272         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6273         submit_info[1].pNext = NULL;
6274         submit_info[1].commandBufferCount = 1;
6275         submit_info[1].pCommandBuffers = &command_buffer[1];
6276         submit_info[1].waitSemaphoreCount = 1;
6277         submit_info[1].pWaitSemaphores = &semaphore;
6278         submit_info[1].pWaitDstStageMask = flags;
6279         submit_info[1].signalSemaphoreCount = 0;
6280         submit_info[1].pSignalSemaphores = NULL;
6281         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
6282     }
6283
6284     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6285
6286     vkDestroyFence(m_device->device(), fence, nullptr);
6287     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6288     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6289     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6290
6291     m_errorMonitor->VerifyNotFound();
6292 }
6293
6294 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
6295     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
6296                      "state is required but not correctly bound.");
6297
6298     ASSERT_NO_FATAL_FAILURE(InitState());
6299     // Dynamic depth bias
6300     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
6301     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias);
6302     m_errorMonitor->VerifyFound();
6303 }
6304
6305 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
6306     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic "
6307                      "state is required but not correctly bound.");
6308
6309     ASSERT_NO_FATAL_FAILURE(InitState());
6310     // Dynamic line width
6311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
6312     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth);
6313     m_errorMonitor->VerifyFound();
6314 }
6315
6316 TEST_F(VkLayerTest, DynamicViewportNotBound) {
6317     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic "
6318                      "state is required but not correctly bound.");
6319
6320     ASSERT_NO_FATAL_FAILURE(InitState());
6321     // Dynamic viewport state
6322     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, but were not provided");
6323     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
6324     m_errorMonitor->VerifyFound();
6325 }
6326
6327 TEST_F(VkLayerTest, DynamicScissorNotBound) {
6328     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic "
6329                      "state is required but not correctly bound.");
6330
6331     ASSERT_NO_FATAL_FAILURE(InitState());
6332     // Dynamic scissor state
6333     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, but were not provided");
6334     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
6335     m_errorMonitor->VerifyFound();
6336 }
6337
6338 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
6339     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants "
6340                      "dynamic state is required but not correctly bound.");
6341
6342     ASSERT_NO_FATAL_FAILURE(InitState());
6343     // Dynamic blend constant state
6344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6345                                          "Dynamic blend constants state not set for this command buffer");
6346     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend);
6347     m_errorMonitor->VerifyFound();
6348 }
6349
6350 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
6351     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic "
6352                      "state is required but not correctly bound.");
6353
6354     ASSERT_NO_FATAL_FAILURE(InitState());
6355     if (!m_device->phy().features().depthBounds) {
6356         printf("Device does not support depthBounds test; skipped.\n");
6357         return;
6358     }
6359     // Dynamic depth bounds
6360     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6361                                          "Dynamic depth bounds state not set for this command buffer");
6362     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds);
6363     m_errorMonitor->VerifyFound();
6364 }
6365
6366 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
6367     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic "
6368                      "state is required but not correctly bound.");
6369
6370     ASSERT_NO_FATAL_FAILURE(InitState());
6371     // Dynamic stencil read mask
6372     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6373                                          "Dynamic stencil read mask state not set for this command buffer");
6374     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask);
6375     m_errorMonitor->VerifyFound();
6376 }
6377
6378 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
6379     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic"
6380                      " state is required but not correctly bound.");
6381
6382     ASSERT_NO_FATAL_FAILURE(InitState());
6383     // Dynamic stencil write mask
6384     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6385                                          "Dynamic stencil write mask state not set for this command buffer");
6386     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask);
6387     m_errorMonitor->VerifyFound();
6388 }
6389
6390 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
6391     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic "
6392                      "state is required but not correctly bound.");
6393
6394     ASSERT_NO_FATAL_FAILURE(InitState());
6395     // Dynamic stencil reference
6396     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6397                                          "Dynamic stencil reference state not set for this command buffer");
6398     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference);
6399     m_errorMonitor->VerifyFound();
6400 }
6401
6402 TEST_F(VkLayerTest, IndexBufferNotBound) {
6403     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
6404
6405     ASSERT_NO_FATAL_FAILURE(InitState());
6406     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6407                                          "Index buffer object not bound to this command buffer when Indexed ");
6408     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer);
6409     m_errorMonitor->VerifyFound();
6410 }
6411
6412 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
6413     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6414                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
6415                                          "been submitted");
6416
6417     ASSERT_NO_FATAL_FAILURE(InitState());
6418     ASSERT_NO_FATAL_FAILURE(InitViewport());
6419     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6420
6421     // We luck out b/c by default the framework creates CB w/ the
6422     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
6423     BeginCommandBuffer();
6424     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
6425     EndCommandBuffer();
6426
6427     // Bypass framework since it does the waits automatically
6428     VkResult err = VK_SUCCESS;
6429     VkSubmitInfo submit_info;
6430     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6431     submit_info.pNext = NULL;
6432     submit_info.waitSemaphoreCount = 0;
6433     submit_info.pWaitSemaphores = NULL;
6434     submit_info.pWaitDstStageMask = NULL;
6435     submit_info.commandBufferCount = 1;
6436     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6437     submit_info.signalSemaphoreCount = 0;
6438     submit_info.pSignalSemaphores = NULL;
6439
6440     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6441     ASSERT_VK_SUCCESS(err);
6442
6443     // Cause validation error by re-submitting cmd buffer that should only be
6444     // submitted once
6445     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6446
6447     m_errorMonitor->VerifyFound();
6448 }
6449
6450 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
6451     // Initiate Draw w/o a PSO bound
6452     VkResult err;
6453
6454     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of "
6455                                                                         "type "
6456                                                                         "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ");
6457
6458     ASSERT_NO_FATAL_FAILURE(InitState());
6459     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6460
6461     // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
6462     // descriptor from it
6463     VkDescriptorPoolSize ds_type_count = {};
6464     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
6465     ds_type_count.descriptorCount = 1;
6466
6467     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6468     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6469     ds_pool_ci.pNext = NULL;
6470     ds_pool_ci.flags = 0;
6471     ds_pool_ci.maxSets = 1;
6472     ds_pool_ci.poolSizeCount = 1;
6473     ds_pool_ci.pPoolSizes = &ds_type_count;
6474
6475     VkDescriptorPool ds_pool;
6476     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6477     ASSERT_VK_SUCCESS(err);
6478
6479     VkDescriptorSetLayoutBinding dsl_binding = {};
6480     dsl_binding.binding = 0;
6481     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6482     dsl_binding.descriptorCount = 1;
6483     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6484     dsl_binding.pImmutableSamplers = NULL;
6485
6486     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6487     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6488     ds_layout_ci.pNext = NULL;
6489     ds_layout_ci.bindingCount = 1;
6490     ds_layout_ci.pBindings = &dsl_binding;
6491
6492     VkDescriptorSetLayout ds_layout;
6493     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6494     ASSERT_VK_SUCCESS(err);
6495
6496     VkDescriptorSet descriptorSet;
6497     VkDescriptorSetAllocateInfo alloc_info = {};
6498     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6499     alloc_info.descriptorSetCount = 1;
6500     alloc_info.descriptorPool = ds_pool;
6501     alloc_info.pSetLayouts = &ds_layout;
6502     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6503
6504     m_errorMonitor->VerifyFound();
6505
6506     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6507     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6508 }
6509
6510 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
6511     VkResult err;
6512
6513     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6514                                          "It is invalid to call vkFreeDescriptorSets() with a pool created "
6515                                          "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
6516
6517     ASSERT_NO_FATAL_FAILURE(InitState());
6518     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6519
6520     VkDescriptorPoolSize ds_type_count = {};
6521     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6522     ds_type_count.descriptorCount = 1;
6523
6524     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6525     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6526     ds_pool_ci.pNext = NULL;
6527     ds_pool_ci.maxSets = 1;
6528     ds_pool_ci.poolSizeCount = 1;
6529     ds_pool_ci.flags = 0;
6530     // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
6531     // app can only call vkResetDescriptorPool on this pool.;
6532     ds_pool_ci.pPoolSizes = &ds_type_count;
6533
6534     VkDescriptorPool ds_pool;
6535     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6536     ASSERT_VK_SUCCESS(err);
6537
6538     VkDescriptorSetLayoutBinding dsl_binding = {};
6539     dsl_binding.binding = 0;
6540     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6541     dsl_binding.descriptorCount = 1;
6542     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6543     dsl_binding.pImmutableSamplers = NULL;
6544
6545     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6546     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6547     ds_layout_ci.pNext = NULL;
6548     ds_layout_ci.bindingCount = 1;
6549     ds_layout_ci.pBindings = &dsl_binding;
6550
6551     VkDescriptorSetLayout ds_layout;
6552     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6553     ASSERT_VK_SUCCESS(err);
6554
6555     VkDescriptorSet descriptorSet;
6556     VkDescriptorSetAllocateInfo alloc_info = {};
6557     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6558     alloc_info.descriptorSetCount = 1;
6559     alloc_info.descriptorPool = ds_pool;
6560     alloc_info.pSetLayouts = &ds_layout;
6561     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6562     ASSERT_VK_SUCCESS(err);
6563
6564     err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
6565     m_errorMonitor->VerifyFound();
6566
6567     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6568     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6569 }
6570
6571 TEST_F(VkLayerTest, InvalidDescriptorPool) {
6572     // Attempt to clear Descriptor Pool with bad object.
6573     // ObjectTracker should catch this.
6574
6575     ASSERT_NO_FATAL_FAILURE(InitState());
6576     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001");
6577     uint64_t fake_pool_handle = 0xbaad6001;
6578     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
6579     vkResetDescriptorPool(device(), bad_pool, 0);
6580     m_errorMonitor->VerifyFound();
6581 }
6582
6583 TEST_F(VkLayerTest, InvalidDescriptorSet) {
6584     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
6585     // ObjectTracker should catch this.
6586     // Create a valid cmd buffer
6587     // call vkCmdBindDescriptorSets w/ false Descriptor Set
6588
6589     uint64_t fake_set_handle = 0xbaad6001;
6590     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
6591     VkResult err;
6592     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001");
6593
6594     ASSERT_NO_FATAL_FAILURE(InitState());
6595
6596     VkDescriptorSetLayoutBinding layout_bindings[1] = {};
6597     layout_bindings[0].binding = 0;
6598     layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6599     layout_bindings[0].descriptorCount = 1;
6600     layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
6601     layout_bindings[0].pImmutableSamplers = NULL;
6602
6603     VkDescriptorSetLayout descriptor_set_layout;
6604     VkDescriptorSetLayoutCreateInfo dslci = {};
6605     dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6606     dslci.pNext = NULL;
6607     dslci.bindingCount = 1;
6608     dslci.pBindings = layout_bindings;
6609     err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout);
6610     ASSERT_VK_SUCCESS(err);
6611
6612     VkPipelineLayout pipeline_layout;
6613     VkPipelineLayoutCreateInfo plci = {};
6614     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6615     plci.pNext = NULL;
6616     plci.setLayoutCount = 1;
6617     plci.pSetLayouts = &descriptor_set_layout;
6618     err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6619     ASSERT_VK_SUCCESS(err);
6620
6621     BeginCommandBuffer();
6622     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0,
6623                             NULL);
6624     m_errorMonitor->VerifyFound();
6625     EndCommandBuffer();
6626     vkDestroyPipelineLayout(device(), pipeline_layout, NULL);
6627     vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL);
6628 }
6629
6630 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
6631     // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
6632     // ObjectTracker should catch this.
6633     uint64_t fake_layout_handle = 0xbaad6001;
6634     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
6635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001");
6636     ASSERT_NO_FATAL_FAILURE(InitState());
6637     VkPipelineLayout pipeline_layout;
6638     VkPipelineLayoutCreateInfo plci = {};
6639     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6640     plci.pNext = NULL;
6641     plci.setLayoutCount = 1;
6642     plci.pSetLayouts = &bad_layout;
6643     vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6644
6645     m_errorMonitor->VerifyFound();
6646 }
6647
6648 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
6649     TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
6650                      "1) A uniform buffer update must have a valid buffer index."
6651                      "2) When using an array of descriptors in a single WriteDescriptor,"
6652                      "     the descriptor types and stageflags must all be the same."
6653                      "3) Immutable Sampler state must match across descriptors");
6654
6655     const char *invalid_BufferInfo_ErrorMessage =
6656         "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
6657         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
6658         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
6659     const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set ";
6660     const char *immutable_ErrorMessage = "Attempting write update to descriptor set ";
6661
6662     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
6663
6664     ASSERT_NO_FATAL_FAILURE(InitState());
6665     VkDescriptorPoolSize ds_type_count[4] = {};
6666     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6667     ds_type_count[0].descriptorCount = 1;
6668     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6669     ds_type_count[1].descriptorCount = 1;
6670     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6671     ds_type_count[2].descriptorCount = 1;
6672     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
6673     ds_type_count[3].descriptorCount = 1;
6674
6675     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6676     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6677     ds_pool_ci.maxSets = 1;
6678     ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
6679     ds_pool_ci.pPoolSizes = ds_type_count;
6680
6681     VkDescriptorPool ds_pool;
6682     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6683     ASSERT_VK_SUCCESS(err);
6684
6685     VkDescriptorSetLayoutBinding layout_binding[3] = {};
6686     layout_binding[0].binding = 0;
6687     layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6688     layout_binding[0].descriptorCount = 1;
6689     layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
6690     layout_binding[0].pImmutableSamplers = NULL;
6691
6692     layout_binding[1].binding = 1;
6693     layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6694     layout_binding[1].descriptorCount = 1;
6695     layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6696     layout_binding[1].pImmutableSamplers = NULL;
6697
6698     VkSamplerCreateInfo sampler_ci = {};
6699     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6700     sampler_ci.pNext = NULL;
6701     sampler_ci.magFilter = VK_FILTER_NEAREST;
6702     sampler_ci.minFilter = VK_FILTER_NEAREST;
6703     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
6704     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6705     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6706     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6707     sampler_ci.mipLodBias = 1.0;
6708     sampler_ci.anisotropyEnable = VK_FALSE;
6709     sampler_ci.maxAnisotropy = 1;
6710     sampler_ci.compareEnable = VK_FALSE;
6711     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
6712     sampler_ci.minLod = 1.0;
6713     sampler_ci.maxLod = 1.0;
6714     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
6715     sampler_ci.unnormalizedCoordinates = VK_FALSE;
6716     VkSampler sampler;
6717
6718     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
6719     ASSERT_VK_SUCCESS(err);
6720
6721     layout_binding[2].binding = 2;
6722     layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6723     layout_binding[2].descriptorCount = 1;
6724     layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6725     layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
6726
6727     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6728     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6729     ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
6730     ds_layout_ci.pBindings = layout_binding;
6731     VkDescriptorSetLayout ds_layout;
6732     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6733     ASSERT_VK_SUCCESS(err);
6734
6735     VkDescriptorSetAllocateInfo alloc_info = {};
6736     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6737     alloc_info.descriptorSetCount = 1;
6738     alloc_info.descriptorPool = ds_pool;
6739     alloc_info.pSetLayouts = &ds_layout;
6740     VkDescriptorSet descriptorSet;
6741     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6742     ASSERT_VK_SUCCESS(err);
6743
6744     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6745     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6746     pipeline_layout_ci.pNext = NULL;
6747     pipeline_layout_ci.setLayoutCount = 1;
6748     pipeline_layout_ci.pSetLayouts = &ds_layout;
6749
6750     VkPipelineLayout pipeline_layout;
6751     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6752     ASSERT_VK_SUCCESS(err);
6753
6754     VkWriteDescriptorSet descriptor_write = {};
6755     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6756     descriptor_write.dstSet = descriptorSet;
6757     descriptor_write.dstBinding = 0;
6758     descriptor_write.descriptorCount = 1;
6759     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6760
6761     // 1) The uniform buffer is intentionally invalid here
6762     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6763     m_errorMonitor->VerifyFound();
6764
6765     // Create a buffer to update the descriptor with
6766     uint32_t qfi = 0;
6767     VkBufferCreateInfo buffCI = {};
6768     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6769     buffCI.size = 1024;
6770     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
6771     buffCI.queueFamilyIndexCount = 1;
6772     buffCI.pQueueFamilyIndices = &qfi;
6773
6774     VkBuffer dyub;
6775     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
6776     ASSERT_VK_SUCCESS(err);
6777     VkDescriptorBufferInfo buffInfo = {};
6778     buffInfo.buffer = dyub;
6779     buffInfo.offset = 0;
6780     buffInfo.range = 1024;
6781
6782     descriptor_write.pBufferInfo = &buffInfo;
6783     descriptor_write.descriptorCount = 2;
6784
6785     // 2) The stateFlags don't match between the first and second descriptor
6786     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
6787     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6788     m_errorMonitor->VerifyFound();
6789
6790     // 3) The second descriptor has a null_ptr pImmutableSamplers and
6791     // the third descriptor contains an immutable sampler
6792     descriptor_write.dstBinding = 1;
6793     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6794
6795     // Make pImageInfo index non-null to avoid complaints of it missing
6796     VkDescriptorImageInfo imageInfo = {};
6797     imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6798     descriptor_write.pImageInfo = &imageInfo;
6799     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
6800     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6801     m_errorMonitor->VerifyFound();
6802
6803     vkDestroyBuffer(m_device->device(), dyub, NULL);
6804     vkDestroySampler(m_device->device(), sampler, NULL);
6805     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
6806     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6807     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6808 }
6809
6810 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
6811     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
6812                      "due to a buffer dependency being destroyed.");
6813     ASSERT_NO_FATAL_FAILURE(InitState());
6814
6815     VkBuffer buffer;
6816     VkDeviceMemory mem;
6817     VkMemoryRequirements mem_reqs;
6818
6819     VkBufferCreateInfo buf_info = {};
6820     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6821     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
6822     buf_info.size = 256;
6823     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
6824     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
6825     ASSERT_VK_SUCCESS(err);
6826
6827     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
6828
6829     VkMemoryAllocateInfo alloc_info = {};
6830     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6831     alloc_info.allocationSize = 256;
6832     bool pass = false;
6833     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6834     if (!pass) {
6835         vkDestroyBuffer(m_device->device(), buffer, NULL);
6836         return;
6837     }
6838     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
6839     ASSERT_VK_SUCCESS(err);
6840
6841     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
6842     ASSERT_VK_SUCCESS(err);
6843
6844     m_commandBuffer->BeginCommandBuffer();
6845     vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
6846     m_commandBuffer->EndCommandBuffer();
6847
6848     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
6849     // Destroy buffer dependency prior to submit to cause ERROR
6850     vkDestroyBuffer(m_device->device(), buffer, NULL);
6851
6852     VkSubmitInfo submit_info = {};
6853     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6854     submit_info.commandBufferCount = 1;
6855     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6856     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6857
6858     m_errorMonitor->VerifyFound();
6859     vkFreeMemory(m_device->handle(), mem, NULL);
6860 }
6861
6862 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
6863     TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
6864
6865     ASSERT_NO_FATAL_FAILURE(InitState());
6866     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6867
6868     VkDescriptorPoolSize ds_type_count;
6869     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6870     ds_type_count.descriptorCount = 1;
6871
6872     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6873     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6874     ds_pool_ci.maxSets = 1;
6875     ds_pool_ci.poolSizeCount = 1;
6876     ds_pool_ci.pPoolSizes = &ds_type_count;
6877
6878     VkDescriptorPool ds_pool;
6879     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6880     ASSERT_VK_SUCCESS(err);
6881
6882     VkDescriptorSetLayoutBinding layout_binding;
6883     layout_binding.binding = 0;
6884     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6885     layout_binding.descriptorCount = 1;
6886     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6887     layout_binding.pImmutableSamplers = NULL;
6888
6889     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6890     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6891     ds_layout_ci.bindingCount = 1;
6892     ds_layout_ci.pBindings = &layout_binding;
6893     VkDescriptorSetLayout ds_layout;
6894     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6895     ASSERT_VK_SUCCESS(err);
6896
6897     VkDescriptorSetAllocateInfo alloc_info = {};
6898     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6899     alloc_info.descriptorSetCount = 1;
6900     alloc_info.descriptorPool = ds_pool;
6901     alloc_info.pSetLayouts = &ds_layout;
6902     VkDescriptorSet descriptor_set;
6903     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
6904     ASSERT_VK_SUCCESS(err);
6905
6906     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6907     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6908     pipeline_layout_ci.pNext = NULL;
6909     pipeline_layout_ci.setLayoutCount = 1;
6910     pipeline_layout_ci.pSetLayouts = &ds_layout;
6911
6912     VkPipelineLayout pipeline_layout;
6913     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6914     ASSERT_VK_SUCCESS(err);
6915
6916     VkBuffer buffer;
6917     uint32_t queue_family_index = 0;
6918     VkBufferCreateInfo buffer_create_info = {};
6919     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6920     buffer_create_info.size = 1024;
6921     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
6922     buffer_create_info.queueFamilyIndexCount = 1;
6923     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
6924
6925     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
6926     ASSERT_VK_SUCCESS(err);
6927
6928     VkMemoryRequirements memory_reqs;
6929     VkDeviceMemory buffer_memory;
6930
6931     VkMemoryAllocateInfo memory_info = {};
6932     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6933     memory_info.allocationSize = 0;
6934     memory_info.memoryTypeIndex = 0;
6935
6936     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
6937     memory_info.allocationSize = memory_reqs.size;
6938     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
6939     ASSERT_TRUE(pass);
6940
6941     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
6942     ASSERT_VK_SUCCESS(err);
6943     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
6944     ASSERT_VK_SUCCESS(err);
6945
6946     VkBufferView view;
6947     VkBufferViewCreateInfo bvci = {};
6948     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
6949     bvci.buffer = buffer;
6950     bvci.format = VK_FORMAT_R8_UNORM;
6951     bvci.range = VK_WHOLE_SIZE;
6952
6953     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
6954     ASSERT_VK_SUCCESS(err);
6955
6956     VkWriteDescriptorSet descriptor_write = {};
6957     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6958     descriptor_write.dstSet = descriptor_set;
6959     descriptor_write.dstBinding = 0;
6960     descriptor_write.descriptorCount = 1;
6961     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6962     descriptor_write.pTexelBufferView = &view;
6963
6964     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6965
6966     char const *vsSource = "#version 450\n"
6967                            "\n"
6968                            "out gl_PerVertex { \n"
6969                            "    vec4 gl_Position;\n"
6970                            "};\n"
6971                            "void main(){\n"
6972                            "   gl_Position = vec4(1);\n"
6973                            "}\n";
6974     char const *fsSource = "#version 450\n"
6975                            "\n"
6976                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
6977                            "layout(location=0) out vec4 x;\n"
6978                            "void main(){\n"
6979                            "   x = imageLoad(s, 0);\n"
6980                            "}\n";
6981     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
6982     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6983     VkPipelineObj pipe(m_device);
6984     pipe.AddShader(&vs);
6985     pipe.AddShader(&fs);
6986     pipe.AddColorAttachment();
6987     pipe.CreateVKPipeline(pipeline_layout, renderPass());
6988
6989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
6990     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
6991
6992     BeginCommandBuffer();
6993     VkViewport viewport = {0, 0, 16, 16, 0, 1};
6994     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
6995     VkRect2D scissor = {{0, 0}, {16, 16}};
6996     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
6997     // Bind pipeline to cmd buffer
6998     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
6999     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7000                             &descriptor_set, 0, nullptr);
7001     Draw(1, 0, 0, 0);
7002     EndCommandBuffer();
7003
7004     // Delete BufferView in order to invalidate cmd buffer
7005     vkDestroyBufferView(m_device->device(), view, NULL);
7006     // Now attempt submit of cmd buffer
7007     VkSubmitInfo submit_info = {};
7008     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7009     submit_info.commandBufferCount = 1;
7010     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7011     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7012     m_errorMonitor->VerifyFound();
7013
7014     // Clean-up
7015     vkDestroyBuffer(m_device->device(), buffer, NULL);
7016     vkFreeMemory(m_device->device(), buffer_memory, NULL);
7017     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7018     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7019     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7020 }
7021
7022 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
7023     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7024                      "due to an image dependency being destroyed.");
7025     ASSERT_NO_FATAL_FAILURE(InitState());
7026
7027     VkImage image;
7028     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7029     VkImageCreateInfo image_create_info = {};
7030     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7031     image_create_info.pNext = NULL;
7032     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7033     image_create_info.format = tex_format;
7034     image_create_info.extent.width = 32;
7035     image_create_info.extent.height = 32;
7036     image_create_info.extent.depth = 1;
7037     image_create_info.mipLevels = 1;
7038     image_create_info.arrayLayers = 1;
7039     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7040     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7041     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7042     image_create_info.flags = 0;
7043     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7044     ASSERT_VK_SUCCESS(err);
7045     // Have to bind memory to image before recording cmd in cmd buffer using it
7046     VkMemoryRequirements mem_reqs;
7047     VkDeviceMemory image_mem;
7048     bool pass;
7049     VkMemoryAllocateInfo mem_alloc = {};
7050     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7051     mem_alloc.pNext = NULL;
7052     mem_alloc.memoryTypeIndex = 0;
7053     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7054     mem_alloc.allocationSize = mem_reqs.size;
7055     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7056     ASSERT_TRUE(pass);
7057     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7058     ASSERT_VK_SUCCESS(err);
7059     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
7060     ASSERT_VK_SUCCESS(err);
7061
7062     m_commandBuffer->BeginCommandBuffer();
7063     VkClearColorValue ccv;
7064     ccv.float32[0] = 1.0f;
7065     ccv.float32[1] = 1.0f;
7066     ccv.float32[2] = 1.0f;
7067     ccv.float32[3] = 1.0f;
7068     VkImageSubresourceRange isr = {};
7069     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7070     isr.baseArrayLayer = 0;
7071     isr.baseMipLevel = 0;
7072     isr.layerCount = 1;
7073     isr.levelCount = 1;
7074     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7075     m_commandBuffer->EndCommandBuffer();
7076
7077     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7078     // Destroy image dependency prior to submit to cause ERROR
7079     vkDestroyImage(m_device->device(), image, NULL);
7080
7081     VkSubmitInfo submit_info = {};
7082     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7083     submit_info.commandBufferCount = 1;
7084     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7085     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7086
7087     m_errorMonitor->VerifyFound();
7088     vkFreeMemory(m_device->device(), image_mem, nullptr);
7089 }
7090
7091 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
7092     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7093                      "due to a framebuffer image dependency being destroyed.");
7094     VkFormatProperties format_properties;
7095     VkResult err = VK_SUCCESS;
7096     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7097     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
7098         return;
7099     }
7100
7101     ASSERT_NO_FATAL_FAILURE(InitState());
7102     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7103
7104     VkImageCreateInfo image_ci = {};
7105     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7106     image_ci.pNext = NULL;
7107     image_ci.imageType = VK_IMAGE_TYPE_2D;
7108     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7109     image_ci.extent.width = 32;
7110     image_ci.extent.height = 32;
7111     image_ci.extent.depth = 1;
7112     image_ci.mipLevels = 1;
7113     image_ci.arrayLayers = 1;
7114     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7115     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7116     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7117     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7118     image_ci.flags = 0;
7119     VkImage image;
7120     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7121
7122     VkMemoryRequirements memory_reqs;
7123     VkDeviceMemory image_memory;
7124     bool pass;
7125     VkMemoryAllocateInfo memory_info = {};
7126     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7127     memory_info.pNext = NULL;
7128     memory_info.allocationSize = 0;
7129     memory_info.memoryTypeIndex = 0;
7130     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7131     memory_info.allocationSize = memory_reqs.size;
7132     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7133     ASSERT_TRUE(pass);
7134     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7135     ASSERT_VK_SUCCESS(err);
7136     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7137     ASSERT_VK_SUCCESS(err);
7138
7139     VkImageViewCreateInfo ivci = {
7140         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7141         nullptr,
7142         0,
7143         image,
7144         VK_IMAGE_VIEW_TYPE_2D,
7145         VK_FORMAT_B8G8R8A8_UNORM,
7146         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7147         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7148     };
7149     VkImageView view;
7150     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7151     ASSERT_VK_SUCCESS(err);
7152
7153     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
7154     VkFramebuffer fb;
7155     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7156     ASSERT_VK_SUCCESS(err);
7157
7158     // Just use default renderpass with our framebuffer
7159     m_renderPassBeginInfo.framebuffer = fb;
7160     // Create Null cmd buffer for submit
7161     BeginCommandBuffer();
7162     EndCommandBuffer();
7163     // Destroy image attached to framebuffer to invalidate cmd buffer
7164     vkDestroyImage(m_device->device(), image, NULL);
7165     // Now attempt to submit cmd buffer and verify error
7166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7167     QueueCommandBuffer(false);
7168     m_errorMonitor->VerifyFound();
7169
7170     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7171     vkDestroyImageView(m_device->device(), view, nullptr);
7172     vkFreeMemory(m_device->device(), image_memory, nullptr);
7173 }
7174
7175 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
7176     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
7177     VkFormatProperties format_properties;
7178     VkResult err = VK_SUCCESS;
7179     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7180
7181     ASSERT_NO_FATAL_FAILURE(InitState());
7182     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7183
7184     VkImageCreateInfo image_ci = {};
7185     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7186     image_ci.pNext = NULL;
7187     image_ci.imageType = VK_IMAGE_TYPE_2D;
7188     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7189     image_ci.extent.width = 256;
7190     image_ci.extent.height = 256;
7191     image_ci.extent.depth = 1;
7192     image_ci.mipLevels = 1;
7193     image_ci.arrayLayers = 1;
7194     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7195     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7196     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
7197     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7198     image_ci.flags = 0;
7199     VkImage image;
7200     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7201
7202     VkMemoryRequirements memory_reqs;
7203     VkDeviceMemory image_memory;
7204     bool pass;
7205     VkMemoryAllocateInfo memory_info = {};
7206     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7207     memory_info.pNext = NULL;
7208     memory_info.allocationSize = 0;
7209     memory_info.memoryTypeIndex = 0;
7210     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7211     memory_info.allocationSize = memory_reqs.size;
7212     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7213     ASSERT_TRUE(pass);
7214     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7215     ASSERT_VK_SUCCESS(err);
7216     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7217     ASSERT_VK_SUCCESS(err);
7218
7219     VkImageViewCreateInfo ivci = {
7220         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7221         nullptr,
7222         0,
7223         image,
7224         VK_IMAGE_VIEW_TYPE_2D,
7225         VK_FORMAT_B8G8R8A8_UNORM,
7226         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7227         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7228     };
7229     VkImageView view;
7230     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7231     ASSERT_VK_SUCCESS(err);
7232
7233     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
7234     VkFramebuffer fb;
7235     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7236     ASSERT_VK_SUCCESS(err);
7237
7238     // Just use default renderpass with our framebuffer
7239     m_renderPassBeginInfo.framebuffer = fb;
7240     // Create Null cmd buffer for submit
7241     BeginCommandBuffer();
7242     EndCommandBuffer();
7243     // Submit cmd buffer to put it (and attached imageView) in-flight
7244     VkSubmitInfo submit_info = {};
7245     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7246     submit_info.commandBufferCount = 1;
7247     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7248     // Submit cmd buffer to put framebuffer and children in-flight
7249     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7250     // Destroy image attached to framebuffer while in-flight
7251     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
7252     vkDestroyImage(m_device->device(), image, NULL);
7253     m_errorMonitor->VerifyFound();
7254     // Wait for queue to complete so we can safely destroy image and other objects
7255     vkQueueWaitIdle(m_device->m_queue);
7256     vkDestroyImage(m_device->device(), image, NULL);
7257     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7258     vkDestroyImageView(m_device->device(), view, nullptr);
7259     vkFreeMemory(m_device->device(), image_memory, nullptr);
7260 }
7261
7262 TEST_F(VkLayerTest, ImageMemoryNotBound) {
7263     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
7264     ASSERT_NO_FATAL_FAILURE(InitState());
7265
7266     VkImage image;
7267     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7268     VkImageCreateInfo image_create_info = {};
7269     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7270     image_create_info.pNext = NULL;
7271     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7272     image_create_info.format = tex_format;
7273     image_create_info.extent.width = 32;
7274     image_create_info.extent.height = 32;
7275     image_create_info.extent.depth = 1;
7276     image_create_info.mipLevels = 1;
7277     image_create_info.arrayLayers = 1;
7278     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7279     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7280     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7281     image_create_info.flags = 0;
7282     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7283     ASSERT_VK_SUCCESS(err);
7284     // Have to bind memory to image before recording cmd in cmd buffer using it
7285     VkMemoryRequirements mem_reqs;
7286     VkDeviceMemory image_mem;
7287     bool pass;
7288     VkMemoryAllocateInfo mem_alloc = {};
7289     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7290     mem_alloc.pNext = NULL;
7291     mem_alloc.memoryTypeIndex = 0;
7292     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7293     mem_alloc.allocationSize = mem_reqs.size;
7294     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7295     ASSERT_TRUE(pass);
7296     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7297     ASSERT_VK_SUCCESS(err);
7298
7299     // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
7300     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7301                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
7302
7303     m_commandBuffer->BeginCommandBuffer();
7304     VkClearColorValue ccv;
7305     ccv.float32[0] = 1.0f;
7306     ccv.float32[1] = 1.0f;
7307     ccv.float32[2] = 1.0f;
7308     ccv.float32[3] = 1.0f;
7309     VkImageSubresourceRange isr = {};
7310     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7311     isr.baseArrayLayer = 0;
7312     isr.baseMipLevel = 0;
7313     isr.layerCount = 1;
7314     isr.levelCount = 1;
7315     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7316     m_commandBuffer->EndCommandBuffer();
7317
7318     m_errorMonitor->VerifyFound();
7319     vkDestroyImage(m_device->device(), image, NULL);
7320     vkFreeMemory(m_device->device(), image_mem, nullptr);
7321 }
7322
7323 TEST_F(VkLayerTest, BufferMemoryNotBound) {
7324     TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
7325     ASSERT_NO_FATAL_FAILURE(InitState());
7326
7327     VkImageObj image(m_device);
7328     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7329                VK_IMAGE_TILING_OPTIMAL, 0);
7330     ASSERT_TRUE(image.initialized());
7331
7332     VkBuffer buffer;
7333     VkDeviceMemory mem;
7334     VkMemoryRequirements mem_reqs;
7335
7336     VkBufferCreateInfo buf_info = {};
7337     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7338     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
7339     buf_info.size = 256;
7340     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7341     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
7342     ASSERT_VK_SUCCESS(err);
7343
7344     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
7345
7346     VkMemoryAllocateInfo alloc_info = {};
7347     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7348     alloc_info.allocationSize = 256;
7349     bool pass = false;
7350     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
7351     if (!pass) {
7352         vkDestroyBuffer(m_device->device(), buffer, NULL);
7353         return;
7354     }
7355     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
7356     ASSERT_VK_SUCCESS(err);
7357
7358     // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7359     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7360                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
7361     VkBufferImageCopy region = {};
7362     region.bufferRowLength = 128;
7363     region.bufferImageHeight = 128;
7364     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7365
7366     region.imageSubresource.layerCount = 1;
7367     region.imageExtent.height = 4;
7368     region.imageExtent.width = 4;
7369     region.imageExtent.depth = 1;
7370     m_commandBuffer->BeginCommandBuffer();
7371     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7372                            &region);
7373     m_commandBuffer->EndCommandBuffer();
7374
7375     m_errorMonitor->VerifyFound();
7376
7377     vkDestroyBuffer(m_device->device(), buffer, NULL);
7378     vkFreeMemory(m_device->handle(), mem, NULL);
7379 }
7380
7381 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
7382     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7383                      "due to an event dependency being destroyed.");
7384     ASSERT_NO_FATAL_FAILURE(InitState());
7385
7386     VkEvent event;
7387     VkEventCreateInfo evci = {};
7388     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
7389     VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
7390     ASSERT_VK_SUCCESS(result);
7391
7392     m_commandBuffer->BeginCommandBuffer();
7393     vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7394     m_commandBuffer->EndCommandBuffer();
7395
7396     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
7397     // Destroy event dependency prior to submit to cause ERROR
7398     vkDestroyEvent(m_device->device(), event, NULL);
7399
7400     VkSubmitInfo submit_info = {};
7401     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7402     submit_info.commandBufferCount = 1;
7403     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7404     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7405
7406     m_errorMonitor->VerifyFound();
7407 }
7408
7409 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
7410     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7411                      "due to a query pool dependency being destroyed.");
7412     ASSERT_NO_FATAL_FAILURE(InitState());
7413
7414     VkQueryPool query_pool;
7415     VkQueryPoolCreateInfo qpci{};
7416     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7417     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
7418     qpci.queryCount = 1;
7419     VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
7420     ASSERT_VK_SUCCESS(result);
7421
7422     m_commandBuffer->BeginCommandBuffer();
7423     vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
7424     m_commandBuffer->EndCommandBuffer();
7425
7426     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool ");
7427     // Destroy query pool dependency prior to submit to cause ERROR
7428     vkDestroyQueryPool(m_device->device(), query_pool, NULL);
7429
7430     VkSubmitInfo submit_info = {};
7431     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7432     submit_info.commandBufferCount = 1;
7433     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7434     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7435
7436     m_errorMonitor->VerifyFound();
7437 }
7438
7439 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
7440     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7441                      "due to a pipeline dependency being destroyed.");
7442     ASSERT_NO_FATAL_FAILURE(InitState());
7443     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7444
7445     VkResult err;
7446
7447     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7448     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7449
7450     VkPipelineLayout pipeline_layout;
7451     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7452     ASSERT_VK_SUCCESS(err);
7453
7454     VkPipelineViewportStateCreateInfo vp_state_ci = {};
7455     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7456     vp_state_ci.viewportCount = 1;
7457     VkViewport vp = {}; // Just need dummy vp to point to
7458     vp_state_ci.pViewports = &vp;
7459     vp_state_ci.scissorCount = 1;
7460     VkRect2D scissors = {}; // Dummy scissors to point to
7461     vp_state_ci.pScissors = &scissors;
7462
7463     VkPipelineShaderStageCreateInfo shaderStages[2];
7464     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
7465
7466     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7467     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
7468     // but add it to be able to run on more devices
7469     shaderStages[0] = vs.GetStageCreateInfo();
7470     shaderStages[1] = fs.GetStageCreateInfo();
7471
7472     VkPipelineVertexInputStateCreateInfo vi_ci = {};
7473     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7474
7475     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
7476     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7477     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
7478
7479     VkPipelineRasterizationStateCreateInfo rs_ci = {};
7480     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7481     rs_ci.rasterizerDiscardEnable = true;
7482     rs_ci.lineWidth = 1.0f;
7483
7484     VkPipelineColorBlendAttachmentState att = {};
7485     att.blendEnable = VK_FALSE;
7486     att.colorWriteMask = 0xf;
7487
7488     VkPipelineColorBlendStateCreateInfo cb_ci = {};
7489     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7490     cb_ci.attachmentCount = 1;
7491     cb_ci.pAttachments = &att;
7492
7493     VkGraphicsPipelineCreateInfo gp_ci = {};
7494     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7495     gp_ci.stageCount = 2;
7496     gp_ci.pStages = shaderStages;
7497     gp_ci.pVertexInputState = &vi_ci;
7498     gp_ci.pInputAssemblyState = &ia_ci;
7499     gp_ci.pViewportState = &vp_state_ci;
7500     gp_ci.pRasterizationState = &rs_ci;
7501     gp_ci.pColorBlendState = &cb_ci;
7502     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
7503     gp_ci.layout = pipeline_layout;
7504     gp_ci.renderPass = renderPass();
7505
7506     VkPipelineCacheCreateInfo pc_ci = {};
7507     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
7508
7509     VkPipeline pipeline;
7510     VkPipelineCache pipelineCache;
7511     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
7512     ASSERT_VK_SUCCESS(err);
7513
7514     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
7515     ASSERT_VK_SUCCESS(err);
7516
7517     m_commandBuffer->BeginCommandBuffer();
7518     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
7519     m_commandBuffer->EndCommandBuffer();
7520     // Now destroy pipeline in order to cause error when submitting
7521     vkDestroyPipeline(m_device->device(), pipeline, nullptr);
7522
7523     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline ");
7524
7525     VkSubmitInfo submit_info = {};
7526     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7527     submit_info.commandBufferCount = 1;
7528     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7529     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7530
7531     m_errorMonitor->VerifyFound();
7532     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
7533     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7534 }
7535
7536 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
7537     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7538                      "due to a bound descriptor set with a buffer dependency "
7539                      "being destroyed.");
7540     ASSERT_NO_FATAL_FAILURE(InitState());
7541     ASSERT_NO_FATAL_FAILURE(InitViewport());
7542     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7543
7544     VkDescriptorPoolSize ds_type_count = {};
7545     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7546     ds_type_count.descriptorCount = 1;
7547
7548     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7549     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7550     ds_pool_ci.pNext = NULL;
7551     ds_pool_ci.maxSets = 1;
7552     ds_pool_ci.poolSizeCount = 1;
7553     ds_pool_ci.pPoolSizes = &ds_type_count;
7554
7555     VkDescriptorPool ds_pool;
7556     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7557     ASSERT_VK_SUCCESS(err);
7558
7559     VkDescriptorSetLayoutBinding dsl_binding = {};
7560     dsl_binding.binding = 0;
7561     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7562     dsl_binding.descriptorCount = 1;
7563     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7564     dsl_binding.pImmutableSamplers = NULL;
7565
7566     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7567     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7568     ds_layout_ci.pNext = NULL;
7569     ds_layout_ci.bindingCount = 1;
7570     ds_layout_ci.pBindings = &dsl_binding;
7571     VkDescriptorSetLayout ds_layout;
7572     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7573     ASSERT_VK_SUCCESS(err);
7574
7575     VkDescriptorSet descriptorSet;
7576     VkDescriptorSetAllocateInfo alloc_info = {};
7577     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7578     alloc_info.descriptorSetCount = 1;
7579     alloc_info.descriptorPool = ds_pool;
7580     alloc_info.pSetLayouts = &ds_layout;
7581     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7582     ASSERT_VK_SUCCESS(err);
7583
7584     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7585     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7586     pipeline_layout_ci.pNext = NULL;
7587     pipeline_layout_ci.setLayoutCount = 1;
7588     pipeline_layout_ci.pSetLayouts = &ds_layout;
7589
7590     VkPipelineLayout pipeline_layout;
7591     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7592     ASSERT_VK_SUCCESS(err);
7593
7594     // Create a buffer to update the descriptor with
7595     uint32_t qfi = 0;
7596     VkBufferCreateInfo buffCI = {};
7597     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7598     buffCI.size = 1024;
7599     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
7600     buffCI.queueFamilyIndexCount = 1;
7601     buffCI.pQueueFamilyIndices = &qfi;
7602
7603     VkBuffer buffer;
7604     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
7605     ASSERT_VK_SUCCESS(err);
7606     // Allocate memory and bind to buffer so we can make it to the appropriate
7607     // error
7608     VkMemoryAllocateInfo mem_alloc = {};
7609     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7610     mem_alloc.pNext = NULL;
7611     mem_alloc.allocationSize = 1024;
7612     mem_alloc.memoryTypeIndex = 0;
7613
7614     VkMemoryRequirements memReqs;
7615     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
7616     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
7617     if (!pass) {
7618         vkDestroyBuffer(m_device->device(), buffer, NULL);
7619         return;
7620     }
7621
7622     VkDeviceMemory mem;
7623     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
7624     ASSERT_VK_SUCCESS(err);
7625     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7626     ASSERT_VK_SUCCESS(err);
7627     // Correctly update descriptor to avoid "NOT_UPDATED" error
7628     VkDescriptorBufferInfo buffInfo = {};
7629     buffInfo.buffer = buffer;
7630     buffInfo.offset = 0;
7631     buffInfo.range = 1024;
7632
7633     VkWriteDescriptorSet descriptor_write;
7634     memset(&descriptor_write, 0, sizeof(descriptor_write));
7635     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7636     descriptor_write.dstSet = descriptorSet;
7637     descriptor_write.dstBinding = 0;
7638     descriptor_write.descriptorCount = 1;
7639     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7640     descriptor_write.pBufferInfo = &buffInfo;
7641
7642     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7643
7644     // Create PSO to be used for draw-time errors below
7645     char const *vsSource = "#version 450\n"
7646                            "\n"
7647                            "out gl_PerVertex { \n"
7648                            "    vec4 gl_Position;\n"
7649                            "};\n"
7650                            "void main(){\n"
7651                            "   gl_Position = vec4(1);\n"
7652                            "}\n";
7653     char const *fsSource = "#version 450\n"
7654                            "\n"
7655                            "layout(location=0) out vec4 x;\n"
7656                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
7657                            "void main(){\n"
7658                            "   x = vec4(bar.y);\n"
7659                            "}\n";
7660     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7661     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7662     VkPipelineObj pipe(m_device);
7663     pipe.AddShader(&vs);
7664     pipe.AddShader(&fs);
7665     pipe.AddColorAttachment();
7666     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7667
7668     BeginCommandBuffer();
7669     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7670     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7671                             &descriptorSet, 0, NULL);
7672     Draw(1, 0, 0, 0);
7673     EndCommandBuffer();
7674     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
7675     // Destroy buffer should invalidate the cmd buffer, causing error on submit
7676     vkDestroyBuffer(m_device->device(), buffer, NULL);
7677     // Attempt to submit cmd buffer
7678     VkSubmitInfo submit_info = {};
7679     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7680     submit_info.commandBufferCount = 1;
7681     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7682     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7683     m_errorMonitor->VerifyFound();
7684     // Cleanup
7685     vkFreeMemory(m_device->device(), mem, NULL);
7686
7687     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7688     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7689     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7690 }
7691
7692 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
7693     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7694                      "due to a bound descriptor sets with a combined image "
7695                      "sampler having their image, sampler, and descriptor set "
7696                      "each respectively destroyed and then attempting to "
7697                      "submit associated cmd buffers. Attempt to destroy a "
7698                      "DescriptorSet that is in use.");
7699     ASSERT_NO_FATAL_FAILURE(InitState());
7700     ASSERT_NO_FATAL_FAILURE(InitViewport());
7701     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7702
7703     VkDescriptorPoolSize ds_type_count = {};
7704     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7705     ds_type_count.descriptorCount = 1;
7706
7707     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7708     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7709     ds_pool_ci.pNext = NULL;
7710     ds_pool_ci.maxSets = 1;
7711     ds_pool_ci.poolSizeCount = 1;
7712     ds_pool_ci.pPoolSizes = &ds_type_count;
7713
7714     VkDescriptorPool ds_pool;
7715     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7716     ASSERT_VK_SUCCESS(err);
7717
7718     VkDescriptorSetLayoutBinding dsl_binding = {};
7719     dsl_binding.binding = 0;
7720     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7721     dsl_binding.descriptorCount = 1;
7722     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7723     dsl_binding.pImmutableSamplers = NULL;
7724
7725     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7726     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7727     ds_layout_ci.pNext = NULL;
7728     ds_layout_ci.bindingCount = 1;
7729     ds_layout_ci.pBindings = &dsl_binding;
7730     VkDescriptorSetLayout ds_layout;
7731     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7732     ASSERT_VK_SUCCESS(err);
7733
7734     VkDescriptorSet descriptorSet;
7735     VkDescriptorSetAllocateInfo alloc_info = {};
7736     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7737     alloc_info.descriptorSetCount = 1;
7738     alloc_info.descriptorPool = ds_pool;
7739     alloc_info.pSetLayouts = &ds_layout;
7740     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7741     ASSERT_VK_SUCCESS(err);
7742
7743     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7744     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7745     pipeline_layout_ci.pNext = NULL;
7746     pipeline_layout_ci.setLayoutCount = 1;
7747     pipeline_layout_ci.pSetLayouts = &ds_layout;
7748
7749     VkPipelineLayout pipeline_layout;
7750     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7751     ASSERT_VK_SUCCESS(err);
7752
7753     // Create images to update the descriptor with
7754     VkImage image;
7755     VkImage image2;
7756     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7757     const int32_t tex_width = 32;
7758     const int32_t tex_height = 32;
7759     VkImageCreateInfo image_create_info = {};
7760     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7761     image_create_info.pNext = NULL;
7762     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7763     image_create_info.format = tex_format;
7764     image_create_info.extent.width = tex_width;
7765     image_create_info.extent.height = tex_height;
7766     image_create_info.extent.depth = 1;
7767     image_create_info.mipLevels = 1;
7768     image_create_info.arrayLayers = 1;
7769     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7770     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7771     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
7772     image_create_info.flags = 0;
7773     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7774     ASSERT_VK_SUCCESS(err);
7775     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
7776     ASSERT_VK_SUCCESS(err);
7777
7778     VkMemoryRequirements memory_reqs;
7779     VkDeviceMemory image_memory;
7780     bool pass;
7781     VkMemoryAllocateInfo memory_info = {};
7782     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7783     memory_info.pNext = NULL;
7784     memory_info.allocationSize = 0;
7785     memory_info.memoryTypeIndex = 0;
7786     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7787     // Allocate enough memory for both images
7788     memory_info.allocationSize = memory_reqs.size * 2;
7789     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7790     ASSERT_TRUE(pass);
7791     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7792     ASSERT_VK_SUCCESS(err);
7793     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7794     ASSERT_VK_SUCCESS(err);
7795     // Bind second image to memory right after first image
7796     err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
7797     ASSERT_VK_SUCCESS(err);
7798
7799     VkImageViewCreateInfo image_view_create_info = {};
7800     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7801     image_view_create_info.image = image;
7802     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
7803     image_view_create_info.format = tex_format;
7804     image_view_create_info.subresourceRange.layerCount = 1;
7805     image_view_create_info.subresourceRange.baseMipLevel = 0;
7806     image_view_create_info.subresourceRange.levelCount = 1;
7807     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7808
7809     VkImageView view;
7810     VkImageView view2;
7811     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
7812     ASSERT_VK_SUCCESS(err);
7813     image_view_create_info.image = image2;
7814     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
7815     ASSERT_VK_SUCCESS(err);
7816     // Create Samplers
7817     VkSamplerCreateInfo sampler_ci = {};
7818     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
7819     sampler_ci.pNext = NULL;
7820     sampler_ci.magFilter = VK_FILTER_NEAREST;
7821     sampler_ci.minFilter = VK_FILTER_NEAREST;
7822     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
7823     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7824     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7825     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7826     sampler_ci.mipLodBias = 1.0;
7827     sampler_ci.anisotropyEnable = VK_FALSE;
7828     sampler_ci.maxAnisotropy = 1;
7829     sampler_ci.compareEnable = VK_FALSE;
7830     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
7831     sampler_ci.minLod = 1.0;
7832     sampler_ci.maxLod = 1.0;
7833     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
7834     sampler_ci.unnormalizedCoordinates = VK_FALSE;
7835     VkSampler sampler;
7836     VkSampler sampler2;
7837     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7838     ASSERT_VK_SUCCESS(err);
7839     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
7840     ASSERT_VK_SUCCESS(err);
7841     // Update descriptor with image and sampler
7842     VkDescriptorImageInfo img_info = {};
7843     img_info.sampler = sampler;
7844     img_info.imageView = view;
7845     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7846
7847     VkWriteDescriptorSet descriptor_write;
7848     memset(&descriptor_write, 0, sizeof(descriptor_write));
7849     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7850     descriptor_write.dstSet = descriptorSet;
7851     descriptor_write.dstBinding = 0;
7852     descriptor_write.descriptorCount = 1;
7853     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7854     descriptor_write.pImageInfo = &img_info;
7855
7856     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7857
7858     // Create PSO to be used for draw-time errors below
7859     char const *vsSource = "#version 450\n"
7860                            "\n"
7861                            "out gl_PerVertex { \n"
7862                            "    vec4 gl_Position;\n"
7863                            "};\n"
7864                            "void main(){\n"
7865                            "   gl_Position = vec4(1);\n"
7866                            "}\n";
7867     char const *fsSource = "#version 450\n"
7868                            "\n"
7869                            "layout(set=0, binding=0) uniform sampler2D s;\n"
7870                            "layout(location=0) out vec4 x;\n"
7871                            "void main(){\n"
7872                            "   x = texture(s, vec2(1));\n"
7873                            "}\n";
7874     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7875     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7876     VkPipelineObj pipe(m_device);
7877     pipe.AddShader(&vs);
7878     pipe.AddShader(&fs);
7879     pipe.AddColorAttachment();
7880     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7881
7882     // First error case is destroying sampler prior to cmd buffer submission
7883     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler ");
7884     BeginCommandBuffer();
7885     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7886     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7887                             &descriptorSet, 0, NULL);
7888     Draw(1, 0, 0, 0);
7889     EndCommandBuffer();
7890     // Destroy sampler invalidates the cmd buffer, causing error on submit
7891     vkDestroySampler(m_device->device(), sampler, NULL);
7892     // Attempt to submit cmd buffer
7893     VkSubmitInfo submit_info = {};
7894     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7895     submit_info.commandBufferCount = 1;
7896     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7897     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7898     m_errorMonitor->VerifyFound();
7899     // Now re-update descriptor with valid sampler and delete image
7900     img_info.sampler = sampler2;
7901     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7902     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7903     BeginCommandBuffer();
7904     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7905     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7906                             &descriptorSet, 0, NULL);
7907     Draw(1, 0, 0, 0);
7908     EndCommandBuffer();
7909     // Destroy image invalidates the cmd buffer, causing error on submit
7910     vkDestroyImage(m_device->device(), image, NULL);
7911     // Attempt to submit cmd buffer
7912     submit_info = {};
7913     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7914     submit_info.commandBufferCount = 1;
7915     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7916     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7917     m_errorMonitor->VerifyFound();
7918     // Now update descriptor to be valid, but then free descriptor
7919     img_info.imageView = view2;
7920     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7921     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set ");
7922     BeginCommandBuffer();
7923     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7924     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7925                             &descriptorSet, 0, NULL);
7926     Draw(1, 0, 0, 0);
7927     EndCommandBuffer();
7928     // Destroy descriptor set invalidates the cb, causing error on submit
7929     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
7930     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
7931     m_errorMonitor->VerifyFound();
7932     // Attempt to submit cmd buffer
7933     submit_info = {};
7934     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7935     submit_info.commandBufferCount = 1;
7936     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7937     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7938     m_errorMonitor->VerifyFound();
7939     // Cleanup
7940     vkFreeMemory(m_device->device(), image_memory, NULL);
7941     vkDestroySampler(m_device->device(), sampler2, NULL);
7942     vkDestroyImage(m_device->device(), image2, NULL);
7943     vkDestroyImageView(m_device->device(), view, NULL);
7944     vkDestroyImageView(m_device->device(), view2, NULL);
7945     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7946     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7947     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7948 }
7949
7950 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
7951     TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
7952     ASSERT_NO_FATAL_FAILURE(InitState());
7953     ASSERT_NO_FATAL_FAILURE(InitViewport());
7954     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7955
7956     VkDescriptorPoolSize ds_type_count = {};
7957     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7958     ds_type_count.descriptorCount = 1;
7959
7960     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7961     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7962     ds_pool_ci.pNext = NULL;
7963     ds_pool_ci.maxSets = 1;
7964     ds_pool_ci.poolSizeCount = 1;
7965     ds_pool_ci.pPoolSizes = &ds_type_count;
7966
7967     VkDescriptorPool ds_pool;
7968     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7969     ASSERT_VK_SUCCESS(err);
7970
7971     VkDescriptorSetLayoutBinding dsl_binding = {};
7972     dsl_binding.binding = 0;
7973     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7974     dsl_binding.descriptorCount = 1;
7975     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7976     dsl_binding.pImmutableSamplers = NULL;
7977
7978     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7979     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7980     ds_layout_ci.pNext = NULL;
7981     ds_layout_ci.bindingCount = 1;
7982     ds_layout_ci.pBindings = &dsl_binding;
7983     VkDescriptorSetLayout ds_layout;
7984     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7985     ASSERT_VK_SUCCESS(err);
7986
7987     VkDescriptorSet descriptorSet;
7988     VkDescriptorSetAllocateInfo alloc_info = {};
7989     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7990     alloc_info.descriptorSetCount = 1;
7991     alloc_info.descriptorPool = ds_pool;
7992     alloc_info.pSetLayouts = &ds_layout;
7993     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7994     ASSERT_VK_SUCCESS(err);
7995
7996     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7997     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7998     pipeline_layout_ci.pNext = NULL;
7999     pipeline_layout_ci.setLayoutCount = 1;
8000     pipeline_layout_ci.pSetLayouts = &ds_layout;
8001
8002     VkPipelineLayout pipeline_layout;
8003     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8004     ASSERT_VK_SUCCESS(err);
8005
8006     // Create images to update the descriptor with
8007     VkImage image;
8008     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8009     const int32_t tex_width = 32;
8010     const int32_t tex_height = 32;
8011     VkImageCreateInfo image_create_info = {};
8012     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8013     image_create_info.pNext = NULL;
8014     image_create_info.imageType = VK_IMAGE_TYPE_2D;
8015     image_create_info.format = tex_format;
8016     image_create_info.extent.width = tex_width;
8017     image_create_info.extent.height = tex_height;
8018     image_create_info.extent.depth = 1;
8019     image_create_info.mipLevels = 1;
8020     image_create_info.arrayLayers = 1;
8021     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
8022     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
8023     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8024     image_create_info.flags = 0;
8025     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
8026     ASSERT_VK_SUCCESS(err);
8027     // Initially bind memory to avoid error at bind view time. We'll break binding before update.
8028     VkMemoryRequirements memory_reqs;
8029     VkDeviceMemory image_memory;
8030     bool pass;
8031     VkMemoryAllocateInfo memory_info = {};
8032     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8033     memory_info.pNext = NULL;
8034     memory_info.allocationSize = 0;
8035     memory_info.memoryTypeIndex = 0;
8036     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
8037     // Allocate enough memory for image
8038     memory_info.allocationSize = memory_reqs.size;
8039     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
8040     ASSERT_TRUE(pass);
8041     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
8042     ASSERT_VK_SUCCESS(err);
8043     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
8044     ASSERT_VK_SUCCESS(err);
8045
8046     VkImageViewCreateInfo image_view_create_info = {};
8047     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8048     image_view_create_info.image = image;
8049     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
8050     image_view_create_info.format = tex_format;
8051     image_view_create_info.subresourceRange.layerCount = 1;
8052     image_view_create_info.subresourceRange.baseMipLevel = 0;
8053     image_view_create_info.subresourceRange.levelCount = 1;
8054     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8055
8056     VkImageView view;
8057     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
8058     ASSERT_VK_SUCCESS(err);
8059     // Create Samplers
8060     VkSamplerCreateInfo sampler_ci = {};
8061     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
8062     sampler_ci.pNext = NULL;
8063     sampler_ci.magFilter = VK_FILTER_NEAREST;
8064     sampler_ci.minFilter = VK_FILTER_NEAREST;
8065     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
8066     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8067     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8068     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8069     sampler_ci.mipLodBias = 1.0;
8070     sampler_ci.anisotropyEnable = VK_FALSE;
8071     sampler_ci.maxAnisotropy = 1;
8072     sampler_ci.compareEnable = VK_FALSE;
8073     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
8074     sampler_ci.minLod = 1.0;
8075     sampler_ci.maxLod = 1.0;
8076     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
8077     sampler_ci.unnormalizedCoordinates = VK_FALSE;
8078     VkSampler sampler;
8079     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8080     ASSERT_VK_SUCCESS(err);
8081     // Update descriptor with image and sampler
8082     VkDescriptorImageInfo img_info = {};
8083     img_info.sampler = sampler;
8084     img_info.imageView = view;
8085     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8086
8087     VkWriteDescriptorSet descriptor_write;
8088     memset(&descriptor_write, 0, sizeof(descriptor_write));
8089     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8090     descriptor_write.dstSet = descriptorSet;
8091     descriptor_write.dstBinding = 0;
8092     descriptor_write.descriptorCount = 1;
8093     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8094     descriptor_write.pImageInfo = &img_info;
8095     // Break memory binding and attempt update
8096     vkFreeMemory(m_device->device(), image_memory, nullptr);
8097     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8098                                          " previously bound memory was freed. Memory must not be freed prior to this operation.");
8099     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8100                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8101     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8102     m_errorMonitor->VerifyFound();
8103     // Cleanup
8104     vkDestroyImage(m_device->device(), image, NULL);
8105     vkDestroySampler(m_device->device(), sampler, NULL);
8106     vkDestroyImageView(m_device->device(), view, NULL);
8107     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8108     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8109     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8110 }
8111
8112 TEST_F(VkLayerTest, InvalidPipeline) {
8113     // Attempt to bind an invalid Pipeline to a valid Command Buffer
8114     // ObjectTracker should catch this.
8115     // Create a valid cmd buffer
8116     // call vkCmdBindPipeline w/ false Pipeline
8117     uint64_t fake_pipeline_handle = 0xbaad6001;
8118     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
8119     ASSERT_NO_FATAL_FAILURE(InitState());
8120     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8121
8122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
8123     BeginCommandBuffer();
8124     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
8125     m_errorMonitor->VerifyFound();
8126
8127     // Now issue a draw call with no pipeline bound
8128     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8129     Draw(1, 0, 0, 0);
8130     m_errorMonitor->VerifyFound();
8131
8132     // Finally same check once more but with Dispatch/Compute
8133     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8134     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
8135     vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
8136     m_errorMonitor->VerifyFound();
8137 }
8138
8139 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
8140     TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
8141     VkResult err;
8142
8143     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
8144
8145     ASSERT_NO_FATAL_FAILURE(InitState());
8146     ASSERT_NO_FATAL_FAILURE(InitViewport());
8147     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8148     VkDescriptorPoolSize ds_type_count = {};
8149     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8150     ds_type_count.descriptorCount = 1;
8151
8152     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8153     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8154     ds_pool_ci.pNext = NULL;
8155     ds_pool_ci.maxSets = 1;
8156     ds_pool_ci.poolSizeCount = 1;
8157     ds_pool_ci.pPoolSizes = &ds_type_count;
8158
8159     VkDescriptorPool ds_pool;
8160     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8161     ASSERT_VK_SUCCESS(err);
8162
8163     VkDescriptorSetLayoutBinding dsl_binding = {};
8164     dsl_binding.binding = 0;
8165     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8166     dsl_binding.descriptorCount = 1;
8167     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8168     dsl_binding.pImmutableSamplers = NULL;
8169
8170     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8171     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8172     ds_layout_ci.pNext = NULL;
8173     ds_layout_ci.bindingCount = 1;
8174     ds_layout_ci.pBindings = &dsl_binding;
8175     VkDescriptorSetLayout ds_layout;
8176     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8177     ASSERT_VK_SUCCESS(err);
8178
8179     VkDescriptorSet descriptorSet;
8180     VkDescriptorSetAllocateInfo alloc_info = {};
8181     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8182     alloc_info.descriptorSetCount = 1;
8183     alloc_info.descriptorPool = ds_pool;
8184     alloc_info.pSetLayouts = &ds_layout;
8185     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8186     ASSERT_VK_SUCCESS(err);
8187
8188     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8189     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8190     pipeline_layout_ci.pNext = NULL;
8191     pipeline_layout_ci.setLayoutCount = 1;
8192     pipeline_layout_ci.pSetLayouts = &ds_layout;
8193
8194     VkPipelineLayout pipeline_layout;
8195     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8196     ASSERT_VK_SUCCESS(err);
8197
8198     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8199     //  We shouldn't need a fragment shader but add it to be able to run
8200     //  on more devices
8201     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8202
8203     VkPipelineObj pipe(m_device);
8204     pipe.AddShader(&vs);
8205     pipe.AddShader(&fs);
8206     pipe.AddColorAttachment();
8207     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8208
8209     BeginCommandBuffer();
8210     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8211     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8212                             &descriptorSet, 0, NULL);
8213
8214     m_errorMonitor->VerifyFound();
8215
8216     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8217     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8218     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8219 }
8220
8221 TEST_F(VkLayerTest, InvalidBufferViewObject) {
8222     // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
8223     VkResult err;
8224
8225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer "
8226                                                                         "descriptor with invalid buffer view");
8227
8228     ASSERT_NO_FATAL_FAILURE(InitState());
8229     VkDescriptorPoolSize ds_type_count = {};
8230     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8231     ds_type_count.descriptorCount = 1;
8232
8233     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8234     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8235     ds_pool_ci.pNext = NULL;
8236     ds_pool_ci.maxSets = 1;
8237     ds_pool_ci.poolSizeCount = 1;
8238     ds_pool_ci.pPoolSizes = &ds_type_count;
8239
8240     VkDescriptorPool ds_pool;
8241     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8242     ASSERT_VK_SUCCESS(err);
8243
8244     VkDescriptorSetLayoutBinding dsl_binding = {};
8245     dsl_binding.binding = 0;
8246     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8247     dsl_binding.descriptorCount = 1;
8248     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8249     dsl_binding.pImmutableSamplers = NULL;
8250
8251     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8252     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8253     ds_layout_ci.pNext = NULL;
8254     ds_layout_ci.bindingCount = 1;
8255     ds_layout_ci.pBindings = &dsl_binding;
8256     VkDescriptorSetLayout ds_layout;
8257     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8258     ASSERT_VK_SUCCESS(err);
8259
8260     VkDescriptorSet descriptorSet;
8261     VkDescriptorSetAllocateInfo alloc_info = {};
8262     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8263     alloc_info.descriptorSetCount = 1;
8264     alloc_info.descriptorPool = ds_pool;
8265     alloc_info.pSetLayouts = &ds_layout;
8266     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8267     ASSERT_VK_SUCCESS(err);
8268
8269     VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object
8270     VkWriteDescriptorSet descriptor_write;
8271     memset(&descriptor_write, 0, sizeof(descriptor_write));
8272     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8273     descriptor_write.dstSet = descriptorSet;
8274     descriptor_write.dstBinding = 0;
8275     descriptor_write.descriptorCount = 1;
8276     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8277     descriptor_write.pTexelBufferView = &view;
8278
8279     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8280
8281     m_errorMonitor->VerifyFound();
8282
8283     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8284     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8285 }
8286
8287 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
8288     TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
8289
8290     VkResult err;
8291     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8292                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8293
8294     ASSERT_NO_FATAL_FAILURE(InitState());
8295
8296     // Create a buffer with no bound memory and then attempt to create
8297     // a buffer view.
8298     VkBufferCreateInfo buff_ci = {};
8299     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8300     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
8301     buff_ci.size = 256;
8302     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8303     VkBuffer buffer;
8304     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
8305     ASSERT_VK_SUCCESS(err);
8306
8307     VkBufferViewCreateInfo buff_view_ci = {};
8308     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8309     buff_view_ci.buffer = buffer;
8310     buff_view_ci.format = VK_FORMAT_R8_UNORM;
8311     buff_view_ci.range = VK_WHOLE_SIZE;
8312     VkBufferView buff_view;
8313     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
8314
8315     m_errorMonitor->VerifyFound();
8316     vkDestroyBuffer(m_device->device(), buffer, NULL);
8317     // If last error is success, it still created the view, so delete it.
8318     if (err == VK_SUCCESS) {
8319         vkDestroyBufferView(m_device->device(), buff_view, NULL);
8320     }
8321 }
8322
8323 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
8324     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
8325     // cases:
8326     // 1. No dynamicOffset supplied
8327     // 2. Too many dynamicOffsets supplied
8328     // 3. Dynamic offset oversteps buffer being updated
8329     VkResult err;
8330     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only "
8331                                                                         "0 dynamicOffsets are left in "
8332                                                                         "pDynamicOffsets ");
8333
8334     ASSERT_NO_FATAL_FAILURE(InitState());
8335     ASSERT_NO_FATAL_FAILURE(InitViewport());
8336     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8337
8338     VkDescriptorPoolSize ds_type_count = {};
8339     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8340     ds_type_count.descriptorCount = 1;
8341
8342     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8343     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8344     ds_pool_ci.pNext = NULL;
8345     ds_pool_ci.maxSets = 1;
8346     ds_pool_ci.poolSizeCount = 1;
8347     ds_pool_ci.pPoolSizes = &ds_type_count;
8348
8349     VkDescriptorPool ds_pool;
8350     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8351     ASSERT_VK_SUCCESS(err);
8352
8353     VkDescriptorSetLayoutBinding dsl_binding = {};
8354     dsl_binding.binding = 0;
8355     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8356     dsl_binding.descriptorCount = 1;
8357     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8358     dsl_binding.pImmutableSamplers = NULL;
8359
8360     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8361     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8362     ds_layout_ci.pNext = NULL;
8363     ds_layout_ci.bindingCount = 1;
8364     ds_layout_ci.pBindings = &dsl_binding;
8365     VkDescriptorSetLayout ds_layout;
8366     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8367     ASSERT_VK_SUCCESS(err);
8368
8369     VkDescriptorSet descriptorSet;
8370     VkDescriptorSetAllocateInfo alloc_info = {};
8371     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8372     alloc_info.descriptorSetCount = 1;
8373     alloc_info.descriptorPool = ds_pool;
8374     alloc_info.pSetLayouts = &ds_layout;
8375     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8376     ASSERT_VK_SUCCESS(err);
8377
8378     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8379     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8380     pipeline_layout_ci.pNext = NULL;
8381     pipeline_layout_ci.setLayoutCount = 1;
8382     pipeline_layout_ci.pSetLayouts = &ds_layout;
8383
8384     VkPipelineLayout pipeline_layout;
8385     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8386     ASSERT_VK_SUCCESS(err);
8387
8388     // Create a buffer to update the descriptor with
8389     uint32_t qfi = 0;
8390     VkBufferCreateInfo buffCI = {};
8391     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8392     buffCI.size = 1024;
8393     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8394     buffCI.queueFamilyIndexCount = 1;
8395     buffCI.pQueueFamilyIndices = &qfi;
8396
8397     VkBuffer dyub;
8398     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8399     ASSERT_VK_SUCCESS(err);
8400     // Allocate memory and bind to buffer so we can make it to the appropriate
8401     // error
8402     VkMemoryAllocateInfo mem_alloc = {};
8403     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8404     mem_alloc.pNext = NULL;
8405     mem_alloc.allocationSize = 1024;
8406     mem_alloc.memoryTypeIndex = 0;
8407
8408     VkMemoryRequirements memReqs;
8409     vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
8410     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
8411     if (!pass) {
8412         vkDestroyBuffer(m_device->device(), dyub, NULL);
8413         return;
8414     }
8415
8416     VkDeviceMemory mem;
8417     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
8418     ASSERT_VK_SUCCESS(err);
8419     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8420     ASSERT_VK_SUCCESS(err);
8421     // Correctly update descriptor to avoid "NOT_UPDATED" error
8422     VkDescriptorBufferInfo buffInfo = {};
8423     buffInfo.buffer = dyub;
8424     buffInfo.offset = 0;
8425     buffInfo.range = 1024;
8426
8427     VkWriteDescriptorSet descriptor_write;
8428     memset(&descriptor_write, 0, sizeof(descriptor_write));
8429     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8430     descriptor_write.dstSet = descriptorSet;
8431     descriptor_write.dstBinding = 0;
8432     descriptor_write.descriptorCount = 1;
8433     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8434     descriptor_write.pBufferInfo = &buffInfo;
8435
8436     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8437
8438     BeginCommandBuffer();
8439     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8440                             &descriptorSet, 0, NULL);
8441     m_errorMonitor->VerifyFound();
8442     uint32_t pDynOff[2] = {512, 756};
8443     // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
8444     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8445                                          "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
8446     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8447                             &descriptorSet, 2, pDynOff);
8448     m_errorMonitor->VerifyFound();
8449     // Finally cause error due to dynamicOffset being too big
8450     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with "
8451                                                                         "offset 0 and range 1024 that "
8452                                                                         "oversteps the buffer size of 1024");
8453     // Create PSO to be used for draw-time errors below
8454     char const *vsSource = "#version 450\n"
8455                            "\n"
8456                            "out gl_PerVertex { \n"
8457                            "    vec4 gl_Position;\n"
8458                            "};\n"
8459                            "void main(){\n"
8460                            "   gl_Position = vec4(1);\n"
8461                            "}\n";
8462     char const *fsSource = "#version 450\n"
8463                            "\n"
8464                            "layout(location=0) out vec4 x;\n"
8465                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8466                            "void main(){\n"
8467                            "   x = vec4(bar.y);\n"
8468                            "}\n";
8469     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8470     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8471     VkPipelineObj pipe(m_device);
8472     pipe.AddShader(&vs);
8473     pipe.AddShader(&fs);
8474     pipe.AddColorAttachment();
8475     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8476
8477     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8478     // This update should succeed, but offset size of 512 will overstep buffer
8479     // /w range 1024 & size 1024
8480     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8481                             &descriptorSet, 1, pDynOff);
8482     Draw(1, 0, 0, 0);
8483     m_errorMonitor->VerifyFound();
8484
8485     vkDestroyBuffer(m_device->device(), dyub, NULL);
8486     vkFreeMemory(m_device->device(), mem, NULL);
8487
8488     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8489     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8490     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8491 }
8492
8493 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
8494     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
8495                      "that doesn't have memory bound");
8496     VkResult err;
8497     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8498                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8499     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8500                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8501
8502     ASSERT_NO_FATAL_FAILURE(InitState());
8503     ASSERT_NO_FATAL_FAILURE(InitViewport());
8504     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8505
8506     VkDescriptorPoolSize ds_type_count = {};
8507     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8508     ds_type_count.descriptorCount = 1;
8509
8510     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8511     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8512     ds_pool_ci.pNext = NULL;
8513     ds_pool_ci.maxSets = 1;
8514     ds_pool_ci.poolSizeCount = 1;
8515     ds_pool_ci.pPoolSizes = &ds_type_count;
8516
8517     VkDescriptorPool ds_pool;
8518     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8519     ASSERT_VK_SUCCESS(err);
8520
8521     VkDescriptorSetLayoutBinding dsl_binding = {};
8522     dsl_binding.binding = 0;
8523     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8524     dsl_binding.descriptorCount = 1;
8525     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8526     dsl_binding.pImmutableSamplers = NULL;
8527
8528     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8529     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8530     ds_layout_ci.pNext = NULL;
8531     ds_layout_ci.bindingCount = 1;
8532     ds_layout_ci.pBindings = &dsl_binding;
8533     VkDescriptorSetLayout ds_layout;
8534     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8535     ASSERT_VK_SUCCESS(err);
8536
8537     VkDescriptorSet descriptorSet;
8538     VkDescriptorSetAllocateInfo alloc_info = {};
8539     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8540     alloc_info.descriptorSetCount = 1;
8541     alloc_info.descriptorPool = ds_pool;
8542     alloc_info.pSetLayouts = &ds_layout;
8543     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8544     ASSERT_VK_SUCCESS(err);
8545
8546     // Create a buffer to update the descriptor with
8547     uint32_t qfi = 0;
8548     VkBufferCreateInfo buffCI = {};
8549     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8550     buffCI.size = 1024;
8551     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8552     buffCI.queueFamilyIndexCount = 1;
8553     buffCI.pQueueFamilyIndices = &qfi;
8554
8555     VkBuffer dyub;
8556     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8557     ASSERT_VK_SUCCESS(err);
8558
8559     // Attempt to update descriptor without binding memory to it
8560     VkDescriptorBufferInfo buffInfo = {};
8561     buffInfo.buffer = dyub;
8562     buffInfo.offset = 0;
8563     buffInfo.range = 1024;
8564
8565     VkWriteDescriptorSet descriptor_write;
8566     memset(&descriptor_write, 0, sizeof(descriptor_write));
8567     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8568     descriptor_write.dstSet = descriptorSet;
8569     descriptor_write.dstBinding = 0;
8570     descriptor_write.descriptorCount = 1;
8571     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8572     descriptor_write.pBufferInfo = &buffInfo;
8573
8574     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8575     m_errorMonitor->VerifyFound();
8576
8577     vkDestroyBuffer(m_device->device(), dyub, NULL);
8578     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8579     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8580 }
8581
8582 TEST_F(VkLayerTest, InvalidPushConstants) {
8583     VkResult err;
8584     ASSERT_NO_FATAL_FAILURE(InitState());
8585     ASSERT_NO_FATAL_FAILURE(InitViewport());
8586     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8587
8588     VkPipelineLayout pipeline_layout;
8589     VkPushConstantRange pc_range = {};
8590     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8591     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8592     pipeline_layout_ci.pushConstantRangeCount = 1;
8593     pipeline_layout_ci.pPushConstantRanges = &pc_range;
8594
8595     //
8596     // Check for invalid push constant ranges in pipeline layouts.
8597     //
8598     struct PipelineLayoutTestCase {
8599         VkPushConstantRange const range;
8600         char const *msg;
8601     };
8602
8603     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
8604     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
8605         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
8606          "vkCreatePipelineLayout() call has push constants index 0 with "
8607          "size 0."},
8608         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8609          "vkCreatePipelineLayout() call has push constants index 0 with "
8610          "size 1."},
8611         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8612          "vkCreatePipelineLayout() call has push constants index 0 with "
8613          "size 1."},
8614         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
8615          "vkCreatePipelineLayout() call has push constants index 0 with "
8616          "size 0."},
8617         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8618          "vkCreatePipelineLayout() call has push constants index 0 with "
8619          "offset 1. Offset must"},
8620         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big},
8621          "vkCreatePipelineLayout() call has push constants index 0 "
8622          "with offset "},
8623         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
8624          "vkCreatePipelineLayout() call has push constants "
8625          "index 0 with offset "},
8626         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
8627          "vkCreatePipelineLayout() call has push constants index 0 "
8628          "with offset "},
8629         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
8630          "vkCreatePipelineLayout() call has push "
8631          "constants index 0 with offset "},
8632         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
8633          "vkCreatePipelineLayout() call has push "
8634          "constants index 0 with offset "},
8635     }};
8636
8637     // Check for invalid offset and size
8638     for (const auto &iter : range_tests) {
8639         pc_range = iter.range;
8640         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8641         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8642         m_errorMonitor->VerifyFound();
8643         if (VK_SUCCESS == err) {
8644             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8645         }
8646     }
8647
8648     // Check for invalid stage flag
8649     pc_range.offset = 0;
8650     pc_range.size = 16;
8651     pc_range.stageFlags = 0;
8652     m_errorMonitor->SetDesiredFailureMsg(
8653         VK_DEBUG_REPORT_ERROR_BIT_EXT,
8654         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
8655     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8656     m_errorMonitor->VerifyFound();
8657     if (VK_SUCCESS == err) {
8658         vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8659     }
8660
8661     // Check for overlapping ranges
8662     const uint32_t ranges_per_test = 5;
8663     struct OverlappingRangeTestCase {
8664         VkPushConstantRange const ranges[ranges_per_test];
8665         char const *msg;
8666     };
8667
8668     const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = {
8669         {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8670            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
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           "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
8675          {
8676              {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8677               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8678               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8679               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8680               {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8681              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
8682          },
8683          {
8684              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8685               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8686               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8687               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8688               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8689              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
8690          },
8691          {
8692              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8693               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8694               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8695               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8696               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8697              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
8698          },
8699          {
8700              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8701               {VK_SHADER_STAGE_VERTEX_BIT, 32, 4},
8702               {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
8703               {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
8704               {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
8705              "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
8706          }}};
8707
8708     for (const auto &iter : overlapping_range_tests) {
8709         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8710         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
8711         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg);
8712         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8713         m_errorMonitor->VerifyFound();
8714         if (VK_SUCCESS == err) {
8715             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8716         }
8717     }
8718
8719     // Run some positive tests to make sure overlap checking in the layer is OK
8720     const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8721                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8722                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8723                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
8724                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8725                                                                                    ""},
8726                                                                                   {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
8727                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
8728                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
8729                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
8730                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8731                                                                                    ""}}};
8732     for (const auto &iter : overlapping_range_tests_pos) {
8733         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8734         m_errorMonitor->ExpectSuccess();
8735         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8736         m_errorMonitor->VerifyNotFound();
8737         if (VK_SUCCESS == err) {
8738             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8739         }
8740     }
8741
8742     //
8743     // CmdPushConstants tests
8744     //
8745     const uint8_t dummy_values[100] = {};
8746
8747     // Check for invalid offset and size and if range is within layout range(s)
8748     const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
8749         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
8750         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8751          "vkCmdPushConstants() call has push constants with size 1. Size "
8752          "must be greater than zero and a multiple of 4."},
8753         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8754          "vkCmdPushConstants() call has push constants with size 1. Size "
8755          "must be greater than zero and a multiple of 4."},
8756         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8757          "vkCmdPushConstants() call has push constants with offset 1. "
8758          "Offset must be a multiple of 4."},
8759         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8760          "vkCmdPushConstants() call has push constants with offset 1. "
8761          "Offset must be a multiple of 4."},
8762         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8763          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8764          "0x1 not within flag-matching ranges in pipeline layout"},
8765         {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8},
8766          "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = "
8767          "0x1 not within flag-matching ranges in pipeline layout"},
8768         {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8},
8769          "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = "
8770          "0x1 not within flag-matching ranges in pipeline layout"},
8771         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80},
8772          "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = "
8773          "0x1 not within flag-matching ranges in pipeline layout"},
8774         {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
8775          "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in "
8776          "any of the ranges in pipeline layout"},
8777         {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
8778          "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
8779          "any of the ranges in pipeline layout"},
8780     }};
8781
8782     BeginCommandBuffer();
8783
8784     // Setup ranges: [0,16) [64,80)
8785     const VkPushConstantRange pc_range2[] = {
8786         {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
8787     };
8788     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange);
8789     pipeline_layout_ci.pPushConstantRanges = pc_range2;
8790     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8791     ASSERT_VK_SUCCESS(err);
8792     for (const auto &iter : cmd_range_tests) {
8793         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8794         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8795                            iter.range.size, dummy_values);
8796         m_errorMonitor->VerifyFound();
8797     }
8798
8799     // Check for invalid stage flag
8800     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
8801     vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
8802     m_errorMonitor->VerifyFound();
8803     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8804
8805     // overlapping range tests with cmd
8806     const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{
8807         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8808          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8809          "0x1 not within flag-matching ranges in pipeline layout"},
8810         {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8811          "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = "
8812          "0x1 not within flag-matching ranges in pipeline layout"},
8813         {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16},
8814          "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
8815          "0x1 not within flag-matching ranges in pipeline layout"},
8816     }};
8817     // Setup ranges:  [0,16), [20,36), [36,44), [44,52), [80,92)
8818     const VkPushConstantRange pc_range3[] = {
8819         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8820         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
8821     };
8822     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
8823     pipeline_layout_ci.pPushConstantRanges = pc_range3;
8824     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8825     ASSERT_VK_SUCCESS(err);
8826     for (const auto &iter : cmd_overlap_tests) {
8827         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8828         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8829                            iter.range.size, dummy_values);
8830         m_errorMonitor->VerifyFound();
8831     }
8832     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8833
8834     // positive overlapping range tests with cmd
8835     const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
8836         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
8837         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
8838         {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
8839         {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
8840     }};
8841     // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
8842     const VkPushConstantRange pc_range4[] = {
8843         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8844         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 24},
8845     };
8846     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
8847     pipeline_layout_ci.pPushConstantRanges = pc_range4;
8848     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8849     ASSERT_VK_SUCCESS(err);
8850     for (const auto &iter : cmd_overlap_tests_pos) {
8851         m_errorMonitor->ExpectSuccess();
8852         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8853                            iter.range.size, dummy_values);
8854         m_errorMonitor->VerifyNotFound();
8855     }
8856     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8857
8858     EndCommandBuffer();
8859 }
8860
8861 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
8862     // Test various desriptorSet errors with bad binding combinations
8863     VkResult err;
8864
8865     ASSERT_NO_FATAL_FAILURE(InitState());
8866     ASSERT_NO_FATAL_FAILURE(InitViewport());
8867     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8868
8869     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
8870     VkImageTiling tiling;
8871     VkFormatProperties format_properties;
8872     vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
8873     if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8874         tiling = VK_IMAGE_TILING_LINEAR;
8875     } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8876         tiling = VK_IMAGE_TILING_OPTIMAL;
8877     } else {
8878         printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
8879                "skipped.\n");
8880         return;
8881     }
8882
8883     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
8884     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
8885     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8886     ds_type_count[0].descriptorCount = 10;
8887     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8888     ds_type_count[1].descriptorCount = 2;
8889     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8890     ds_type_count[2].descriptorCount = 2;
8891     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
8892     ds_type_count[3].descriptorCount = 5;
8893     // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
8894     // type
8895     // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
8896     ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8897     ds_type_count[4].descriptorCount = 2;
8898
8899     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8900     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8901     ds_pool_ci.pNext = NULL;
8902     ds_pool_ci.maxSets = 5;
8903     ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
8904     ds_pool_ci.pPoolSizes = ds_type_count;
8905
8906     VkDescriptorPool ds_pool;
8907     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8908     ASSERT_VK_SUCCESS(err);
8909
8910     static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
8911     VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
8912     dsl_binding[0].binding = 0;
8913     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8914     dsl_binding[0].descriptorCount = 5;
8915     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
8916     dsl_binding[0].pImmutableSamplers = NULL;
8917
8918     // Create layout identical to set0 layout but w/ different stageFlags
8919     VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
8920     dsl_fs_stage_only.binding = 0;
8921     dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8922     dsl_fs_stage_only.descriptorCount = 5;
8923     dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at
8924                                                                  // bind time
8925     dsl_fs_stage_only.pImmutableSamplers = NULL;
8926     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8927     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8928     ds_layout_ci.pNext = NULL;
8929     ds_layout_ci.bindingCount = 1;
8930     ds_layout_ci.pBindings = dsl_binding;
8931     static const uint32_t NUM_LAYOUTS = 4;
8932     VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {};
8933     VkDescriptorSetLayout ds_layout_fs_only = {};
8934     // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
8935     // layout for error case
8936     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]);
8937     ASSERT_VK_SUCCESS(err);
8938     ds_layout_ci.pBindings = &dsl_fs_stage_only;
8939     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only);
8940     ASSERT_VK_SUCCESS(err);
8941     dsl_binding[0].binding = 0;
8942     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8943     dsl_binding[0].descriptorCount = 2;
8944     dsl_binding[1].binding = 1;
8945     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8946     dsl_binding[1].descriptorCount = 2;
8947     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
8948     dsl_binding[1].pImmutableSamplers = NULL;
8949     ds_layout_ci.pBindings = dsl_binding;
8950     ds_layout_ci.bindingCount = 2;
8951     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]);
8952     ASSERT_VK_SUCCESS(err);
8953     dsl_binding[0].binding = 0;
8954     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8955     dsl_binding[0].descriptorCount = 5;
8956     ds_layout_ci.bindingCount = 1;
8957     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]);
8958     ASSERT_VK_SUCCESS(err);
8959     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8960     dsl_binding[0].descriptorCount = 2;
8961     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]);
8962     ASSERT_VK_SUCCESS(err);
8963
8964     static const uint32_t NUM_SETS = 4;
8965     VkDescriptorSet descriptorSet[NUM_SETS] = {};
8966     VkDescriptorSetAllocateInfo alloc_info = {};
8967     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8968     alloc_info.descriptorSetCount = NUM_LAYOUTS;
8969     alloc_info.descriptorPool = ds_pool;
8970     alloc_info.pSetLayouts = ds_layout;
8971     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
8972     ASSERT_VK_SUCCESS(err);
8973     VkDescriptorSet ds0_fs_only = {};
8974     alloc_info.descriptorSetCount = 1;
8975     alloc_info.pSetLayouts = &ds_layout_fs_only;
8976     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
8977     ASSERT_VK_SUCCESS(err);
8978
8979     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8980     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8981     pipeline_layout_ci.pNext = NULL;
8982     pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS;
8983     pipeline_layout_ci.pSetLayouts = ds_layout;
8984
8985     VkPipelineLayout pipeline_layout;
8986     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8987     ASSERT_VK_SUCCESS(err);
8988     // Create pipelineLayout with only one setLayout
8989     pipeline_layout_ci.setLayoutCount = 1;
8990     VkPipelineLayout single_pipe_layout;
8991     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout);
8992     ASSERT_VK_SUCCESS(err);
8993     // Create pipelineLayout with 2 descriptor setLayout at index 0
8994     pipeline_layout_ci.pSetLayouts = &ds_layout[3];
8995     VkPipelineLayout pipe_layout_one_desc;
8996     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc);
8997     ASSERT_VK_SUCCESS(err);
8998     // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
8999     pipeline_layout_ci.pSetLayouts = &ds_layout[2];
9000     VkPipelineLayout pipe_layout_five_samp;
9001     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp);
9002     ASSERT_VK_SUCCESS(err);
9003     // Create pipelineLayout with UB type, but stageFlags for FS only
9004     pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only;
9005     VkPipelineLayout pipe_layout_fs_only;
9006     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only);
9007     ASSERT_VK_SUCCESS(err);
9008     // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
9009     VkDescriptorSetLayout pl_bad_s0[2] = {};
9010     pl_bad_s0[0] = ds_layout_fs_only;
9011     pl_bad_s0[1] = ds_layout[1];
9012     pipeline_layout_ci.setLayoutCount = 2;
9013     pipeline_layout_ci.pSetLayouts = pl_bad_s0;
9014     VkPipelineLayout pipe_layout_bad_set0;
9015     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0);
9016     ASSERT_VK_SUCCESS(err);
9017
9018     // Create a buffer to update the descriptor with
9019     uint32_t qfi = 0;
9020     VkBufferCreateInfo buffCI = {};
9021     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9022     buffCI.size = 1024;
9023     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
9024     buffCI.queueFamilyIndexCount = 1;
9025     buffCI.pQueueFamilyIndices = &qfi;
9026
9027     VkBuffer dyub;
9028     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
9029     ASSERT_VK_SUCCESS(err);
9030     // Correctly update descriptor to avoid "NOT_UPDATED" error
9031     static const uint32_t NUM_BUFFS = 5;
9032     VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {};
9033     for (uint32_t i = 0; i < NUM_BUFFS; ++i) {
9034         buffInfo[i].buffer = dyub;
9035         buffInfo[i].offset = 0;
9036         buffInfo[i].range = 1024;
9037     }
9038     VkImage image;
9039     const int32_t tex_width = 32;
9040     const int32_t tex_height = 32;
9041     VkImageCreateInfo image_create_info = {};
9042     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9043     image_create_info.pNext = NULL;
9044     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9045     image_create_info.format = tex_format;
9046     image_create_info.extent.width = tex_width;
9047     image_create_info.extent.height = tex_height;
9048     image_create_info.extent.depth = 1;
9049     image_create_info.mipLevels = 1;
9050     image_create_info.arrayLayers = 1;
9051     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9052     image_create_info.tiling = tiling;
9053     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
9054     image_create_info.flags = 0;
9055     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9056     ASSERT_VK_SUCCESS(err);
9057
9058     VkMemoryRequirements memReqs;
9059     VkDeviceMemory imageMem;
9060     bool pass;
9061     VkMemoryAllocateInfo memAlloc = {};
9062     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9063     memAlloc.pNext = NULL;
9064     memAlloc.allocationSize = 0;
9065     memAlloc.memoryTypeIndex = 0;
9066     vkGetImageMemoryRequirements(m_device->device(), image, &memReqs);
9067     memAlloc.allocationSize = memReqs.size;
9068     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
9069     ASSERT_TRUE(pass);
9070     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem);
9071     ASSERT_VK_SUCCESS(err);
9072     err = vkBindImageMemory(m_device->device(), image, imageMem, 0);
9073     ASSERT_VK_SUCCESS(err);
9074
9075     VkImageViewCreateInfo image_view_create_info = {};
9076     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
9077     image_view_create_info.image = image;
9078     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
9079     image_view_create_info.format = tex_format;
9080     image_view_create_info.subresourceRange.layerCount = 1;
9081     image_view_create_info.subresourceRange.baseMipLevel = 0;
9082     image_view_create_info.subresourceRange.levelCount = 1;
9083     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9084
9085     VkImageView view;
9086     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
9087     ASSERT_VK_SUCCESS(err);
9088     VkDescriptorImageInfo imageInfo[4] = {};
9089     imageInfo[0].imageView = view;
9090     imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9091     imageInfo[1].imageView = view;
9092     imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9093     imageInfo[2].imageView = view;
9094     imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9095     imageInfo[3].imageView = view;
9096     imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9097
9098     static const uint32_t NUM_SET_UPDATES = 3;
9099     VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
9100     descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9101     descriptor_write[0].dstSet = descriptorSet[0];
9102     descriptor_write[0].dstBinding = 0;
9103     descriptor_write[0].descriptorCount = 5;
9104     descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9105     descriptor_write[0].pBufferInfo = buffInfo;
9106     descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9107     descriptor_write[1].dstSet = descriptorSet[1];
9108     descriptor_write[1].dstBinding = 0;
9109     descriptor_write[1].descriptorCount = 2;
9110     descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9111     descriptor_write[1].pImageInfo = imageInfo;
9112     descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9113     descriptor_write[2].dstSet = descriptorSet[1];
9114     descriptor_write[2].dstBinding = 1;
9115     descriptor_write[2].descriptorCount = 2;
9116     descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9117     descriptor_write[2].pImageInfo = &imageInfo[2];
9118
9119     vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL);
9120
9121     // Create PSO to be used for draw-time errors below
9122     char const *vsSource = "#version 450\n"
9123                            "\n"
9124                            "out gl_PerVertex {\n"
9125                            "    vec4 gl_Position;\n"
9126                            "};\n"
9127                            "void main(){\n"
9128                            "   gl_Position = vec4(1);\n"
9129                            "}\n";
9130     char const *fsSource = "#version 450\n"
9131                            "\n"
9132                            "layout(location=0) out vec4 x;\n"
9133                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
9134                            "void main(){\n"
9135                            "   x = vec4(bar.y);\n"
9136                            "}\n";
9137     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9138     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9139     VkPipelineObj pipe(m_device);
9140     pipe.AddShader(&vs);
9141     pipe.AddShader(&fs);
9142     pipe.AddColorAttachment();
9143     pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass());
9144
9145     BeginCommandBuffer();
9146
9147     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9148     // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
9149     // of PSO
9150     //  here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
9151     //  cmd_pipeline.c
9152     //  due to the fact that cmd_alloc_dset_data() has not been called in
9153     //  cmd_bind_graphics_pipeline()
9154     // TODO : Want to cause various binding incompatibility issues here to test
9155     // DrawState
9156     //  First cause various verify_layout_compatibility() fails
9157     //  Second disturb early and late sets and verify INFO msgs
9158     // verify_set_layout_compatibility fail cases:
9159     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
9160     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object ");
9161     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
9162                             (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL);
9163     m_errorMonitor->VerifyFound();
9164
9165     // 2. layoutIndex exceeds # of layouts in layout
9166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
9167     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2,
9168                             &descriptorSet[0], 0, NULL);
9169     m_errorMonitor->VerifyFound();
9170
9171     vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL);
9172     // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
9173     // descriptors
9174     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
9175     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1,
9176                             &descriptorSet[0], 0, NULL);
9177     m_errorMonitor->VerifyFound();
9178
9179     vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL);
9180     // 4. same # of descriptors but mismatch in type
9181     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
9182     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1,
9183                             &descriptorSet[0], 0, NULL);
9184     m_errorMonitor->VerifyFound();
9185
9186     vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL);
9187     // 5. same # of descriptors but mismatch in stageFlags
9188     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9189                                          " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
9190     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9191                             &descriptorSet[0], 0, NULL);
9192     m_errorMonitor->VerifyFound();
9193
9194     // Cause INFO messages due to disturbing previously bound Sets
9195     // First bind sets 0 & 1
9196     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9197                             &descriptorSet[0], 0, NULL);
9198     // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout
9199     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed ");
9200     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9201                             &descriptorSet[1], 0, NULL);
9202     m_errorMonitor->VerifyFound();
9203
9204     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9205                             &descriptorSet[0], 0, NULL);
9206     // 2. Disturb set after last bound set
9207     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and "
9208                                                                                       "any subsequent sets were disturbed ");
9209     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9210                             &ds0_fs_only, 0, NULL);
9211     m_errorMonitor->VerifyFound();
9212
9213     // Now that we're done actively using the pipelineLayout that gfx pipeline
9214     //  was created with, we should be able to delete it. Do that now to verify
9215     //  that validation obeys pipelineLayout lifetime
9216     vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
9217
9218     // Cause draw-time errors due to PSO incompatibilities
9219     // 1. Error due to not binding required set (we actually use same code as
9220     // above to disturb set0)
9221     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9222                             &descriptorSet[0], 0, NULL);
9223     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9224                             &descriptorSet[1], 0, NULL);
9225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
9226     Draw(1, 0, 0, 0);
9227     m_errorMonitor->VerifyFound();
9228
9229     vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL);
9230     // 2. Error due to bound set not being compatible with PSO's
9231     // VkPipelineLayout (diff stageFlags in this case)
9232     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9233                             &descriptorSet[0], 0, NULL);
9234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
9235     Draw(1, 0, 0, 0);
9236     m_errorMonitor->VerifyFound();
9237
9238     // Remaining clean-up
9239     for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
9240         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
9241     }
9242     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
9243     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
9244     vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
9245     vkDestroyBuffer(m_device->device(), dyub, NULL);
9246     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9247     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9248     vkFreeMemory(m_device->device(), imageMem, NULL);
9249     vkDestroyImage(m_device->device(), image, NULL);
9250     vkDestroyImageView(m_device->device(), view, NULL);
9251 }
9252
9253 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
9254
9255     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9256                                          "You must call vkBeginCommandBuffer() before this call to ");
9257
9258     ASSERT_NO_FATAL_FAILURE(InitState());
9259     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9260     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
9261     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9262
9263     m_errorMonitor->VerifyFound();
9264 }
9265
9266 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
9267     VkResult err;
9268     VkCommandBuffer draw_cmd;
9269
9270     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter.");
9271
9272     ASSERT_NO_FATAL_FAILURE(InitState());
9273
9274     VkCommandBufferAllocateInfo cmd = {};
9275     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
9276     cmd.pNext = NULL;
9277     cmd.commandPool = m_commandPool;
9278     cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
9279     cmd.commandBufferCount = 1;
9280
9281     err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd);
9282     ASSERT_VK_SUCCESS(err);
9283
9284     // Force the failure by not setting the Renderpass and Framebuffer fields
9285     VkCommandBufferBeginInfo cmd_buf_info = {};
9286     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9287     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9288     cmd_buf_info.pNext = NULL;
9289     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
9290     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9291
9292     // The error should be caught by validation of the BeginCommandBuffer call
9293     vkBeginCommandBuffer(draw_cmd, &cmd_buf_info);
9294
9295     m_errorMonitor->VerifyFound();
9296     vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd);
9297 }
9298
9299 TEST_F(VkLayerTest, CommandBufferResetErrors) {
9300     // Cause error due to Begin while recording CB
9301     // Then cause 2 errors for attempting to reset CB w/o having
9302     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
9303     // which CBs were allocated. Note that this bit is off by default.
9304     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
9305
9306     ASSERT_NO_FATAL_FAILURE(InitState());
9307
9308     // Calls AllocateCommandBuffers
9309     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9310
9311     // Force the failure by setting the Renderpass and Framebuffer fields with
9312     // (fake) data
9313     VkCommandBufferBeginInfo cmd_buf_info = {};
9314     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9315     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9316     cmd_buf_info.pNext = NULL;
9317     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
9318     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9319
9320     // Begin CB to transition to recording state
9321     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9322     // Can't re-begin. This should trigger error
9323     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9324     m_errorMonitor->VerifyFound();
9325
9326     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer ");
9327     VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
9328     // Reset attempt will trigger error due to incorrect CommandPool state
9329     vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags);
9330     m_errorMonitor->VerifyFound();
9331
9332     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from ");
9333     // Transition CB to RECORDED state
9334     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9335     // Now attempting to Begin will implicitly reset, which triggers error
9336     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9337     m_errorMonitor->VerifyFound();
9338 }
9339
9340 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
9341     // Attempt to Create Gfx Pipeline w/o a VS
9342     VkResult err;
9343
9344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
9345
9346     ASSERT_NO_FATAL_FAILURE(InitState());
9347     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9348
9349     VkDescriptorPoolSize ds_type_count = {};
9350     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9351     ds_type_count.descriptorCount = 1;
9352
9353     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9354     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9355     ds_pool_ci.pNext = NULL;
9356     ds_pool_ci.maxSets = 1;
9357     ds_pool_ci.poolSizeCount = 1;
9358     ds_pool_ci.pPoolSizes = &ds_type_count;
9359
9360     VkDescriptorPool ds_pool;
9361     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9362     ASSERT_VK_SUCCESS(err);
9363
9364     VkDescriptorSetLayoutBinding dsl_binding = {};
9365     dsl_binding.binding = 0;
9366     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9367     dsl_binding.descriptorCount = 1;
9368     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9369     dsl_binding.pImmutableSamplers = NULL;
9370
9371     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9372     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9373     ds_layout_ci.pNext = NULL;
9374     ds_layout_ci.bindingCount = 1;
9375     ds_layout_ci.pBindings = &dsl_binding;
9376
9377     VkDescriptorSetLayout ds_layout;
9378     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9379     ASSERT_VK_SUCCESS(err);
9380
9381     VkDescriptorSet descriptorSet;
9382     VkDescriptorSetAllocateInfo alloc_info = {};
9383     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9384     alloc_info.descriptorSetCount = 1;
9385     alloc_info.descriptorPool = ds_pool;
9386     alloc_info.pSetLayouts = &ds_layout;
9387     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9388     ASSERT_VK_SUCCESS(err);
9389
9390     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9391     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9392     pipeline_layout_ci.setLayoutCount = 1;
9393     pipeline_layout_ci.pSetLayouts = &ds_layout;
9394
9395     VkPipelineLayout pipeline_layout;
9396     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9397     ASSERT_VK_SUCCESS(err);
9398
9399     VkViewport vp = {}; // Just need dummy vp to point to
9400     VkRect2D sc = {};   // dummy scissor to point to
9401
9402     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9403     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9404     vp_state_ci.scissorCount = 1;
9405     vp_state_ci.pScissors = &sc;
9406     vp_state_ci.viewportCount = 1;
9407     vp_state_ci.pViewports = &vp;
9408
9409     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9410     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9411     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9412     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9413     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9414     rs_state_ci.depthClampEnable = VK_FALSE;
9415     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9416     rs_state_ci.depthBiasEnable = VK_FALSE;
9417
9418     VkGraphicsPipelineCreateInfo gp_ci = {};
9419     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9420     gp_ci.pViewportState = &vp_state_ci;
9421     gp_ci.pRasterizationState = &rs_state_ci;
9422     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9423     gp_ci.layout = pipeline_layout;
9424     gp_ci.renderPass = renderPass();
9425
9426     VkPipelineCacheCreateInfo pc_ci = {};
9427     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9428     pc_ci.initialDataSize = 0;
9429     pc_ci.pInitialData = 0;
9430
9431     VkPipeline pipeline;
9432     VkPipelineCache pipelineCache;
9433
9434     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9435     ASSERT_VK_SUCCESS(err);
9436     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9437
9438     m_errorMonitor->VerifyFound();
9439
9440     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9441     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9442     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9443     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9444 }
9445 /*// TODO : This test should be good, but needs Tess support in compiler to run
9446 TEST_F(VkLayerTest, InvalidPatchControlPoints)
9447 {
9448     // Attempt to Create Gfx Pipeline w/o a VS
9449     VkResult        err;
9450
9451     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9452         "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
9453 primitive ");
9454
9455     ASSERT_NO_FATAL_FAILURE(InitState());
9456     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9457
9458     VkDescriptorPoolSize ds_type_count = {};
9459         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9460         ds_type_count.descriptorCount = 1;
9461
9462     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9463         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9464         ds_pool_ci.pNext = NULL;
9465         ds_pool_ci.poolSizeCount = 1;
9466         ds_pool_ci.pPoolSizes = &ds_type_count;
9467
9468     VkDescriptorPool ds_pool;
9469     err = vkCreateDescriptorPool(m_device->device(),
9470 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
9471     ASSERT_VK_SUCCESS(err);
9472
9473     VkDescriptorSetLayoutBinding dsl_binding = {};
9474         dsl_binding.binding = 0;
9475         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9476         dsl_binding.descriptorCount = 1;
9477         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9478         dsl_binding.pImmutableSamplers = NULL;
9479
9480     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9481         ds_layout_ci.sType =
9482 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9483         ds_layout_ci.pNext = NULL;
9484         ds_layout_ci.bindingCount = 1;
9485         ds_layout_ci.pBindings = &dsl_binding;
9486
9487     VkDescriptorSetLayout ds_layout;
9488     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
9489 &ds_layout);
9490     ASSERT_VK_SUCCESS(err);
9491
9492     VkDescriptorSet descriptorSet;
9493     err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
9494 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
9495     ASSERT_VK_SUCCESS(err);
9496
9497     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9498         pipeline_layout_ci.sType =
9499 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9500         pipeline_layout_ci.pNext = NULL;
9501         pipeline_layout_ci.setLayoutCount = 1;
9502         pipeline_layout_ci.pSetLayouts = &ds_layout;
9503
9504     VkPipelineLayout pipeline_layout;
9505     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
9506 &pipeline_layout);
9507     ASSERT_VK_SUCCESS(err);
9508
9509     VkPipelineShaderStageCreateInfo shaderStages[3];
9510     memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
9511
9512     VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
9513 this);
9514     // Just using VS txt for Tess shaders as we don't care about functionality
9515     VkShaderObj
9516 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9517 this);
9518     VkShaderObj
9519 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9520 this);
9521
9522     shaderStages[0].sType  =
9523 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9524     shaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
9525     shaderStages[0].shader = vs.handle();
9526     shaderStages[1].sType  =
9527 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9528     shaderStages[1].stage  = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
9529     shaderStages[1].shader = tc.handle();
9530     shaderStages[2].sType  =
9531 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9532     shaderStages[2].stage  = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
9533     shaderStages[2].shader = te.handle();
9534
9535     VkPipelineInputAssemblyStateCreateInfo iaCI = {};
9536         iaCI.sType =
9537 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9538         iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
9539
9540     VkPipelineTessellationStateCreateInfo tsCI = {};
9541         tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
9542         tsCI.patchControlPoints = 0; // This will cause an error
9543
9544     VkGraphicsPipelineCreateInfo gp_ci = {};
9545         gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9546         gp_ci.pNext = NULL;
9547         gp_ci.stageCount = 3;
9548         gp_ci.pStages = shaderStages;
9549         gp_ci.pVertexInputState = NULL;
9550         gp_ci.pInputAssemblyState = &iaCI;
9551         gp_ci.pTessellationState = &tsCI;
9552         gp_ci.pViewportState = NULL;
9553         gp_ci.pRasterizationState = NULL;
9554         gp_ci.pMultisampleState = NULL;
9555         gp_ci.pDepthStencilState = NULL;
9556         gp_ci.pColorBlendState = NULL;
9557         gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9558         gp_ci.layout = pipeline_layout;
9559         gp_ci.renderPass = renderPass();
9560
9561     VkPipelineCacheCreateInfo pc_ci = {};
9562         pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9563         pc_ci.pNext = NULL;
9564         pc_ci.initialSize = 0;
9565         pc_ci.initialData = 0;
9566         pc_ci.maxSize = 0;
9567
9568     VkPipeline pipeline;
9569     VkPipelineCache pipelineCache;
9570
9571     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
9572 &pipelineCache);
9573     ASSERT_VK_SUCCESS(err);
9574     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
9575 &gp_ci, NULL, &pipeline);
9576
9577     m_errorMonitor->VerifyFound();
9578
9579     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9580     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9581     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9582     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9583 }
9584 */
9585 // Set scissor and viewport counts to different numbers
9586 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) {
9587     VkResult err;
9588
9589     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9590                                          "Gfx Pipeline viewport count (1) must match scissor count (0).");
9591
9592     ASSERT_NO_FATAL_FAILURE(InitState());
9593     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9594
9595     VkDescriptorPoolSize ds_type_count = {};
9596     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9597     ds_type_count.descriptorCount = 1;
9598
9599     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9600     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9601     ds_pool_ci.maxSets = 1;
9602     ds_pool_ci.poolSizeCount = 1;
9603     ds_pool_ci.pPoolSizes = &ds_type_count;
9604
9605     VkDescriptorPool ds_pool;
9606     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9607     ASSERT_VK_SUCCESS(err);
9608
9609     VkDescriptorSetLayoutBinding dsl_binding = {};
9610     dsl_binding.binding = 0;
9611     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9612     dsl_binding.descriptorCount = 1;
9613     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9614
9615     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9616     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9617     ds_layout_ci.bindingCount = 1;
9618     ds_layout_ci.pBindings = &dsl_binding;
9619
9620     VkDescriptorSetLayout ds_layout;
9621     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9622     ASSERT_VK_SUCCESS(err);
9623
9624     VkDescriptorSet descriptorSet;
9625     VkDescriptorSetAllocateInfo alloc_info = {};
9626     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9627     alloc_info.descriptorSetCount = 1;
9628     alloc_info.descriptorPool = ds_pool;
9629     alloc_info.pSetLayouts = &ds_layout;
9630     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9631     ASSERT_VK_SUCCESS(err);
9632
9633     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9634     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9635     pipeline_layout_ci.setLayoutCount = 1;
9636     pipeline_layout_ci.pSetLayouts = &ds_layout;
9637
9638     VkPipelineLayout pipeline_layout;
9639     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9640     ASSERT_VK_SUCCESS(err);
9641
9642     VkViewport vp = {}; // Just need dummy vp to point to
9643
9644     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9645     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9646     vp_state_ci.scissorCount = 0;
9647     vp_state_ci.viewportCount = 1; // Count mismatch should cause error
9648     vp_state_ci.pViewports = &vp;
9649
9650     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9651     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9652     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9653     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9654     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9655     rs_state_ci.depthClampEnable = VK_FALSE;
9656     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9657     rs_state_ci.depthBiasEnable = VK_FALSE;
9658
9659     VkPipelineShaderStageCreateInfo shaderStages[2];
9660     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9661
9662     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9663     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9664     // but add it to be able to run on more devices
9665     shaderStages[0] = vs.GetStageCreateInfo();
9666     shaderStages[1] = fs.GetStageCreateInfo();
9667
9668     VkGraphicsPipelineCreateInfo gp_ci = {};
9669     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9670     gp_ci.stageCount = 2;
9671     gp_ci.pStages = shaderStages;
9672     gp_ci.pViewportState = &vp_state_ci;
9673     gp_ci.pRasterizationState = &rs_state_ci;
9674     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9675     gp_ci.layout = pipeline_layout;
9676     gp_ci.renderPass = renderPass();
9677
9678     VkPipelineCacheCreateInfo pc_ci = {};
9679     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9680
9681     VkPipeline pipeline;
9682     VkPipelineCache pipelineCache;
9683
9684     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9685     ASSERT_VK_SUCCESS(err);
9686     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9687
9688     m_errorMonitor->VerifyFound();
9689
9690     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9691     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9692     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9693     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9694 }
9695 // Don't set viewport state in PSO. This is an error b/c we always need this
9696 // state
9697 //  for the counts even if the data is going to be set dynamically.
9698 TEST_F(VkLayerTest, PSOViewportStateNotSet) {
9699     // Attempt to Create Gfx Pipeline w/o a VS
9700     VkResult err;
9701
9702     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if ");
9703
9704     ASSERT_NO_FATAL_FAILURE(InitState());
9705     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9706
9707     VkDescriptorPoolSize ds_type_count = {};
9708     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9709     ds_type_count.descriptorCount = 1;
9710
9711     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9712     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9713     ds_pool_ci.maxSets = 1;
9714     ds_pool_ci.poolSizeCount = 1;
9715     ds_pool_ci.pPoolSizes = &ds_type_count;
9716
9717     VkDescriptorPool ds_pool;
9718     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9719     ASSERT_VK_SUCCESS(err);
9720
9721     VkDescriptorSetLayoutBinding dsl_binding = {};
9722     dsl_binding.binding = 0;
9723     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9724     dsl_binding.descriptorCount = 1;
9725     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9726
9727     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9728     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9729     ds_layout_ci.bindingCount = 1;
9730     ds_layout_ci.pBindings = &dsl_binding;
9731
9732     VkDescriptorSetLayout ds_layout;
9733     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9734     ASSERT_VK_SUCCESS(err);
9735
9736     VkDescriptorSet descriptorSet;
9737     VkDescriptorSetAllocateInfo alloc_info = {};
9738     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9739     alloc_info.descriptorSetCount = 1;
9740     alloc_info.descriptorPool = ds_pool;
9741     alloc_info.pSetLayouts = &ds_layout;
9742     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9743     ASSERT_VK_SUCCESS(err);
9744
9745     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9746     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9747     pipeline_layout_ci.setLayoutCount = 1;
9748     pipeline_layout_ci.pSetLayouts = &ds_layout;
9749
9750     VkPipelineLayout pipeline_layout;
9751     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9752     ASSERT_VK_SUCCESS(err);
9753
9754     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9755     // Set scissor as dynamic to avoid second error
9756     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9757     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9758     dyn_state_ci.dynamicStateCount = 1;
9759     dyn_state_ci.pDynamicStates = &sc_state;
9760
9761     VkPipelineShaderStageCreateInfo shaderStages[2];
9762     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9763
9764     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9765     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9766     // but add it to be able to run on more devices
9767     shaderStages[0] = vs.GetStageCreateInfo();
9768     shaderStages[1] = fs.GetStageCreateInfo();
9769
9770     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9771     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9772     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9773     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9774     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9775     rs_state_ci.depthClampEnable = VK_FALSE;
9776     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9777     rs_state_ci.depthBiasEnable = VK_FALSE;
9778
9779     VkGraphicsPipelineCreateInfo gp_ci = {};
9780     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9781     gp_ci.stageCount = 2;
9782     gp_ci.pStages = shaderStages;
9783     gp_ci.pRasterizationState = &rs_state_ci;
9784     gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state
9785                                  // should cause validation error
9786     gp_ci.pDynamicState = &dyn_state_ci;
9787     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9788     gp_ci.layout = pipeline_layout;
9789     gp_ci.renderPass = renderPass();
9790
9791     VkPipelineCacheCreateInfo pc_ci = {};
9792     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9793
9794     VkPipeline pipeline;
9795     VkPipelineCache pipelineCache;
9796
9797     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9798     ASSERT_VK_SUCCESS(err);
9799     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9800
9801     m_errorMonitor->VerifyFound();
9802
9803     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9804     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9805     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9806     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9807 }
9808 // Create PSO w/o non-zero viewportCount but no viewport data
9809 // Then run second test where dynamic scissor count doesn't match PSO scissor
9810 // count
9811 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) {
9812     VkResult err;
9813
9814     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9815                                          "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
9816
9817     ASSERT_NO_FATAL_FAILURE(InitState());
9818
9819     if (!m_device->phy().features().multiViewport) {
9820         printf("Device does not support multiple viewports/scissors; skipped.\n");
9821         return;
9822     }
9823
9824     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9825
9826     VkDescriptorPoolSize ds_type_count = {};
9827     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9828     ds_type_count.descriptorCount = 1;
9829
9830     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9831     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9832     ds_pool_ci.maxSets = 1;
9833     ds_pool_ci.poolSizeCount = 1;
9834     ds_pool_ci.pPoolSizes = &ds_type_count;
9835
9836     VkDescriptorPool ds_pool;
9837     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9838     ASSERT_VK_SUCCESS(err);
9839
9840     VkDescriptorSetLayoutBinding dsl_binding = {};
9841     dsl_binding.binding = 0;
9842     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9843     dsl_binding.descriptorCount = 1;
9844     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9845
9846     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9847     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9848     ds_layout_ci.bindingCount = 1;
9849     ds_layout_ci.pBindings = &dsl_binding;
9850
9851     VkDescriptorSetLayout ds_layout;
9852     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9853     ASSERT_VK_SUCCESS(err);
9854
9855     VkDescriptorSet descriptorSet;
9856     VkDescriptorSetAllocateInfo alloc_info = {};
9857     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9858     alloc_info.descriptorSetCount = 1;
9859     alloc_info.descriptorPool = ds_pool;
9860     alloc_info.pSetLayouts = &ds_layout;
9861     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9862     ASSERT_VK_SUCCESS(err);
9863
9864     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9865     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9866     pipeline_layout_ci.setLayoutCount = 1;
9867     pipeline_layout_ci.pSetLayouts = &ds_layout;
9868
9869     VkPipelineLayout pipeline_layout;
9870     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9871     ASSERT_VK_SUCCESS(err);
9872
9873     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9874     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9875     vp_state_ci.viewportCount = 1;
9876     vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error
9877     vp_state_ci.scissorCount = 1;
9878     vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error
9879
9880     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9881     // Set scissor as dynamic to avoid that error
9882     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9883     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9884     dyn_state_ci.dynamicStateCount = 1;
9885     dyn_state_ci.pDynamicStates = &sc_state;
9886
9887     VkPipelineShaderStageCreateInfo shaderStages[2];
9888     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9889
9890     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9891     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9892     // but add it to be able to run on more devices
9893     shaderStages[0] = vs.GetStageCreateInfo();
9894     shaderStages[1] = fs.GetStageCreateInfo();
9895
9896     VkPipelineVertexInputStateCreateInfo vi_ci = {};
9897     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
9898     vi_ci.pNext = nullptr;
9899     vi_ci.vertexBindingDescriptionCount = 0;
9900     vi_ci.pVertexBindingDescriptions = nullptr;
9901     vi_ci.vertexAttributeDescriptionCount = 0;
9902     vi_ci.pVertexAttributeDescriptions = nullptr;
9903
9904     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
9905     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9906     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9907
9908     VkPipelineRasterizationStateCreateInfo rs_ci = {};
9909     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9910     rs_ci.pNext = nullptr;
9911
9912     VkPipelineColorBlendAttachmentState att = {};
9913     att.blendEnable = VK_FALSE;
9914     att.colorWriteMask = 0xf;
9915
9916     VkPipelineColorBlendStateCreateInfo cb_ci = {};
9917     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
9918     cb_ci.pNext = nullptr;
9919     cb_ci.attachmentCount = 1;
9920     cb_ci.pAttachments = &att;
9921
9922     VkGraphicsPipelineCreateInfo gp_ci = {};
9923     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9924     gp_ci.stageCount = 2;
9925     gp_ci.pStages = shaderStages;
9926     gp_ci.pVertexInputState = &vi_ci;
9927     gp_ci.pInputAssemblyState = &ia_ci;
9928     gp_ci.pViewportState = &vp_state_ci;
9929     gp_ci.pRasterizationState = &rs_ci;
9930     gp_ci.pColorBlendState = &cb_ci;
9931     gp_ci.pDynamicState = &dyn_state_ci;
9932     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9933     gp_ci.layout = pipeline_layout;
9934     gp_ci.renderPass = renderPass();
9935
9936     VkPipelineCacheCreateInfo pc_ci = {};
9937     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9938
9939     VkPipeline pipeline;
9940     VkPipelineCache pipelineCache;
9941
9942     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9943     ASSERT_VK_SUCCESS(err);
9944     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9945
9946     m_errorMonitor->VerifyFound();
9947
9948     // Now hit second fail case where we set scissor w/ different count than PSO
9949     // First need to successfully create the PSO from above by setting
9950     // pViewports
9951     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
9952
9953     VkViewport vp = {}; // Just need dummy vp to point to
9954     vp_state_ci.pViewports = &vp;
9955     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9956     ASSERT_VK_SUCCESS(err);
9957     BeginCommandBuffer();
9958     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
9959     VkRect2D scissors[1] = {}; // don't care about data
9960     // Count of 2 doesn't match PSO count of 1
9961     vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
9962     Draw(1, 0, 0, 0);
9963
9964     m_errorMonitor->VerifyFound();
9965
9966     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9967     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9968     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9969     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9970     vkDestroyPipeline(m_device->device(), pipeline, NULL);
9971 }
9972 // Create PSO w/o non-zero scissorCount but no scissor data
9973 // Then run second test where dynamic viewportCount doesn't match PSO
9974 // viewportCount
9975 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) {
9976     VkResult err;
9977
9978     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
9979
9980     ASSERT_NO_FATAL_FAILURE(InitState());
9981
9982     if (!m_device->phy().features().multiViewport) {
9983         printf("Device does not support multiple viewports/scissors; skipped.\n");
9984         return;
9985     }
9986
9987     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9988
9989     VkDescriptorPoolSize ds_type_count = {};
9990     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9991     ds_type_count.descriptorCount = 1;
9992
9993     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9994     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9995     ds_pool_ci.maxSets = 1;
9996     ds_pool_ci.poolSizeCount = 1;
9997     ds_pool_ci.pPoolSizes = &ds_type_count;
9998
9999     VkDescriptorPool ds_pool;
10000     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10001     ASSERT_VK_SUCCESS(err);
10002
10003     VkDescriptorSetLayoutBinding dsl_binding = {};
10004     dsl_binding.binding = 0;
10005     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10006     dsl_binding.descriptorCount = 1;
10007     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10008
10009     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10010     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10011     ds_layout_ci.bindingCount = 1;
10012     ds_layout_ci.pBindings = &dsl_binding;
10013
10014     VkDescriptorSetLayout ds_layout;
10015     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10016     ASSERT_VK_SUCCESS(err);
10017
10018     VkDescriptorSet descriptorSet;
10019     VkDescriptorSetAllocateInfo alloc_info = {};
10020     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10021     alloc_info.descriptorSetCount = 1;
10022     alloc_info.descriptorPool = ds_pool;
10023     alloc_info.pSetLayouts = &ds_layout;
10024     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10025     ASSERT_VK_SUCCESS(err);
10026
10027     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10028     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10029     pipeline_layout_ci.setLayoutCount = 1;
10030     pipeline_layout_ci.pSetLayouts = &ds_layout;
10031
10032     VkPipelineLayout pipeline_layout;
10033     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10034     ASSERT_VK_SUCCESS(err);
10035
10036     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10037     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10038     vp_state_ci.scissorCount = 1;
10039     vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error
10040     vp_state_ci.viewportCount = 1;
10041     vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error
10042
10043     VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT;
10044     // Set scissor as dynamic to avoid that error
10045     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10046     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10047     dyn_state_ci.dynamicStateCount = 1;
10048     dyn_state_ci.pDynamicStates = &vp_state;
10049
10050     VkPipelineShaderStageCreateInfo shaderStages[2];
10051     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10052
10053     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10054     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
10055     // but add it to be able to run on more devices
10056     shaderStages[0] = vs.GetStageCreateInfo();
10057     shaderStages[1] = fs.GetStageCreateInfo();
10058
10059     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10060     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10061     vi_ci.pNext = nullptr;
10062     vi_ci.vertexBindingDescriptionCount = 0;
10063     vi_ci.pVertexBindingDescriptions = nullptr;
10064     vi_ci.vertexAttributeDescriptionCount = 0;
10065     vi_ci.pVertexAttributeDescriptions = nullptr;
10066
10067     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10068     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10069     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10070
10071     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10072     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10073     rs_ci.pNext = nullptr;
10074
10075     VkPipelineColorBlendAttachmentState att = {};
10076     att.blendEnable = VK_FALSE;
10077     att.colorWriteMask = 0xf;
10078
10079     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10080     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10081     cb_ci.pNext = nullptr;
10082     cb_ci.attachmentCount = 1;
10083     cb_ci.pAttachments = &att;
10084
10085     VkGraphicsPipelineCreateInfo gp_ci = {};
10086     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10087     gp_ci.stageCount = 2;
10088     gp_ci.pStages = shaderStages;
10089     gp_ci.pVertexInputState = &vi_ci;
10090     gp_ci.pInputAssemblyState = &ia_ci;
10091     gp_ci.pViewportState = &vp_state_ci;
10092     gp_ci.pRasterizationState = &rs_ci;
10093     gp_ci.pColorBlendState = &cb_ci;
10094     gp_ci.pDynamicState = &dyn_state_ci;
10095     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10096     gp_ci.layout = pipeline_layout;
10097     gp_ci.renderPass = renderPass();
10098
10099     VkPipelineCacheCreateInfo pc_ci = {};
10100     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10101
10102     VkPipeline pipeline;
10103     VkPipelineCache pipelineCache;
10104
10105     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10106     ASSERT_VK_SUCCESS(err);
10107     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10108
10109     m_errorMonitor->VerifyFound();
10110
10111     // Now hit second fail case where we set scissor w/ different count than PSO
10112     // First need to successfully create the PSO from above by setting
10113     // pViewports
10114     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
10115
10116     VkRect2D sc = {}; // Just need dummy vp to point to
10117     vp_state_ci.pScissors = &sc;
10118     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10119     ASSERT_VK_SUCCESS(err);
10120     BeginCommandBuffer();
10121     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10122     VkViewport viewports[1] = {}; // don't care about data
10123     // Count of 2 doesn't match PSO count of 1
10124     vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
10125     Draw(1, 0, 0, 0);
10126
10127     m_errorMonitor->VerifyFound();
10128
10129     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10130     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10131     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10132     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10133     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10134 }
10135
10136 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
10137     VkResult err;
10138
10139     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10140
10141     ASSERT_NO_FATAL_FAILURE(InitState());
10142     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10143
10144     VkDescriptorPoolSize ds_type_count = {};
10145     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10146     ds_type_count.descriptorCount = 1;
10147
10148     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10149     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10150     ds_pool_ci.maxSets = 1;
10151     ds_pool_ci.poolSizeCount = 1;
10152     ds_pool_ci.pPoolSizes = &ds_type_count;
10153
10154     VkDescriptorPool ds_pool;
10155     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10156     ASSERT_VK_SUCCESS(err);
10157
10158     VkDescriptorSetLayoutBinding dsl_binding = {};
10159     dsl_binding.binding = 0;
10160     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10161     dsl_binding.descriptorCount = 1;
10162     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10163
10164     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10165     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10166     ds_layout_ci.bindingCount = 1;
10167     ds_layout_ci.pBindings = &dsl_binding;
10168
10169     VkDescriptorSetLayout ds_layout;
10170     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10171     ASSERT_VK_SUCCESS(err);
10172
10173     VkDescriptorSet descriptorSet;
10174     VkDescriptorSetAllocateInfo alloc_info = {};
10175     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10176     alloc_info.descriptorSetCount = 1;
10177     alloc_info.descriptorPool = ds_pool;
10178     alloc_info.pSetLayouts = &ds_layout;
10179     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10180     ASSERT_VK_SUCCESS(err);
10181
10182     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10183     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10184     pipeline_layout_ci.setLayoutCount = 1;
10185     pipeline_layout_ci.pSetLayouts = &ds_layout;
10186
10187     VkPipelineLayout pipeline_layout;
10188     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10189     ASSERT_VK_SUCCESS(err);
10190
10191     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10192     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10193     vp_state_ci.scissorCount = 1;
10194     vp_state_ci.pScissors = NULL;
10195     vp_state_ci.viewportCount = 1;
10196     vp_state_ci.pViewports = NULL;
10197
10198     VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
10199     // Set scissor as dynamic to avoid that error
10200     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10201     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10202     dyn_state_ci.dynamicStateCount = 2;
10203     dyn_state_ci.pDynamicStates = dynamic_states;
10204
10205     VkPipelineShaderStageCreateInfo shaderStages[2];
10206     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10207
10208     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10209     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
10210                    this); // TODO - We shouldn't need a fragment shader
10211                           // but add it to be able to run on more devices
10212     shaderStages[0] = vs.GetStageCreateInfo();
10213     shaderStages[1] = fs.GetStageCreateInfo();
10214
10215     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10216     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10217     vi_ci.pNext = nullptr;
10218     vi_ci.vertexBindingDescriptionCount = 0;
10219     vi_ci.pVertexBindingDescriptions = nullptr;
10220     vi_ci.vertexAttributeDescriptionCount = 0;
10221     vi_ci.pVertexAttributeDescriptions = nullptr;
10222
10223     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10224     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10225     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10226
10227     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10228     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10229     rs_ci.pNext = nullptr;
10230
10231     // Check too low (line width of -1.0f).
10232     rs_ci.lineWidth = -1.0f;
10233
10234     VkPipelineColorBlendAttachmentState att = {};
10235     att.blendEnable = VK_FALSE;
10236     att.colorWriteMask = 0xf;
10237
10238     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10239     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10240     cb_ci.pNext = nullptr;
10241     cb_ci.attachmentCount = 1;
10242     cb_ci.pAttachments = &att;
10243
10244     VkGraphicsPipelineCreateInfo gp_ci = {};
10245     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10246     gp_ci.stageCount = 2;
10247     gp_ci.pStages = shaderStages;
10248     gp_ci.pVertexInputState = &vi_ci;
10249     gp_ci.pInputAssemblyState = &ia_ci;
10250     gp_ci.pViewportState = &vp_state_ci;
10251     gp_ci.pRasterizationState = &rs_ci;
10252     gp_ci.pColorBlendState = &cb_ci;
10253     gp_ci.pDynamicState = &dyn_state_ci;
10254     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10255     gp_ci.layout = pipeline_layout;
10256     gp_ci.renderPass = renderPass();
10257
10258     VkPipelineCacheCreateInfo pc_ci = {};
10259     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10260
10261     VkPipeline pipeline;
10262     VkPipelineCache pipelineCache;
10263
10264     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10265     ASSERT_VK_SUCCESS(err);
10266     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10267
10268     m_errorMonitor->VerifyFound();
10269     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10270
10271     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10272
10273     // Check too high (line width of 65536.0f).
10274     rs_ci.lineWidth = 65536.0f;
10275
10276     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10277     ASSERT_VK_SUCCESS(err);
10278     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10279
10280     m_errorMonitor->VerifyFound();
10281     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10282
10283     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10284
10285     dyn_state_ci.dynamicStateCount = 3;
10286
10287     rs_ci.lineWidth = 1.0f;
10288
10289     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10290     ASSERT_VK_SUCCESS(err);
10291     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10292     BeginCommandBuffer();
10293     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10294
10295     // Check too low with dynamic setting.
10296     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f);
10297     m_errorMonitor->VerifyFound();
10298
10299     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10300
10301     // Check too high with dynamic setting.
10302     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f);
10303     m_errorMonitor->VerifyFound();
10304     EndCommandBuffer();
10305
10306     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10307     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10308     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10309     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10310     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10311 }
10312
10313 TEST_F(VkLayerTest, NullRenderPass) {
10314     // Bind a NULL RenderPass
10315     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10316                                          "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
10317
10318     ASSERT_NO_FATAL_FAILURE(InitState());
10319     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10320
10321     BeginCommandBuffer();
10322     // Don't care about RenderPass handle b/c error should be flagged before
10323     // that
10324     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
10325
10326     m_errorMonitor->VerifyFound();
10327 }
10328
10329 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
10330     // Bind a BeginRenderPass within an active RenderPass
10331     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10332                                          "It is invalid to issue this call inside an active render pass");
10333
10334     ASSERT_NO_FATAL_FAILURE(InitState());
10335     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10336
10337     BeginCommandBuffer();
10338     // Just create a dummy Renderpass that's non-NULL so we can get to the
10339     // proper error
10340     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10341
10342     m_errorMonitor->VerifyFound();
10343 }
10344
10345 TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
10346     m_errorMonitor->ExpectSuccess();
10347
10348     ASSERT_NO_FATAL_FAILURE(InitState());
10349     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10350
10351     BeginCommandBuffer();                                   // framework implicitly begins the renderpass.
10352     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
10353
10354     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
10355     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10356     m_errorMonitor->VerifyNotFound();
10357     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10358     m_errorMonitor->VerifyNotFound();
10359     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10360     m_errorMonitor->VerifyNotFound();
10361
10362     m_commandBuffer->EndCommandBuffer();
10363     m_errorMonitor->VerifyNotFound();
10364 }
10365
10366 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
10367     TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
10368                      "the number of renderPass attachments that use loadOp"
10369                      "VK_ATTACHMENT_LOAD_OP_CLEAR.");
10370
10371     ASSERT_NO_FATAL_FAILURE(InitState());
10372     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10373
10374     // Create a renderPass with a single attachment that uses loadOp CLEAR
10375     VkAttachmentReference attach = {};
10376     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
10377     VkSubpassDescription subpass = {};
10378     subpass.inputAttachmentCount = 1;
10379     subpass.pInputAttachments = &attach;
10380     VkRenderPassCreateInfo rpci = {};
10381     rpci.subpassCount = 1;
10382     rpci.pSubpasses = &subpass;
10383     rpci.attachmentCount = 1;
10384     VkAttachmentDescription attach_desc = {};
10385     attach_desc.format = VK_FORMAT_UNDEFINED;
10386     // Set loadOp to CLEAR
10387     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10388     rpci.pAttachments = &attach_desc;
10389     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10390     VkRenderPass rp;
10391     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
10392
10393     VkCommandBufferInheritanceInfo hinfo = {};
10394     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10395     hinfo.renderPass = VK_NULL_HANDLE;
10396     hinfo.subpass = 0;
10397     hinfo.framebuffer = VK_NULL_HANDLE;
10398     hinfo.occlusionQueryEnable = VK_FALSE;
10399     hinfo.queryFlags = 0;
10400     hinfo.pipelineStatistics = 0;
10401     VkCommandBufferBeginInfo info = {};
10402     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
10403     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10404     info.pInheritanceInfo = &hinfo;
10405
10406     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
10407     VkRenderPassBeginInfo rp_begin = {};
10408     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
10409     rp_begin.pNext = NULL;
10410     rp_begin.renderPass = renderPass();
10411     rp_begin.framebuffer = framebuffer();
10412     rp_begin.clearValueCount = 0; // Should be 1
10413
10414     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but "
10415                                                                         "there must be at least 1 entries in "
10416                                                                         "pClearValues array to account for ");
10417
10418     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
10419
10420     m_errorMonitor->VerifyFound();
10421
10422     vkDestroyRenderPass(m_device->device(), rp, NULL);
10423 }
10424
10425 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
10426
10427     TEST_DESCRIPTION("End a command buffer with an active render pass");
10428
10429     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10430                                          "It is invalid to issue this call inside an active render pass");
10431
10432     ASSERT_NO_FATAL_FAILURE(InitState());
10433     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10434
10435     // The framework's BeginCommandBuffer calls CreateRenderPass
10436     BeginCommandBuffer();
10437
10438     // Call directly into vkEndCommandBuffer instead of the
10439     // the framework's EndCommandBuffer, which inserts a
10440     // vkEndRenderPass
10441     vkEndCommandBuffer(m_commandBuffer->GetBufferHandle());
10442
10443     m_errorMonitor->VerifyFound();
10444
10445     // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
10446     // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
10447 }
10448
10449 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
10450     // Call CmdFillBuffer within an active renderpass
10451     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10452                                          "It is invalid to issue this call inside an active render pass");
10453
10454     ASSERT_NO_FATAL_FAILURE(InitState());
10455     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10456
10457     // Renderpass is started here
10458     BeginCommandBuffer();
10459
10460     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10461     vk_testing::Buffer dstBuffer;
10462     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10463
10464     m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
10465
10466     m_errorMonitor->VerifyFound();
10467 }
10468
10469 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
10470     // Call CmdUpdateBuffer within an active renderpass
10471     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10472                                          "It is invalid to issue this call inside an active render pass");
10473
10474     ASSERT_NO_FATAL_FAILURE(InitState());
10475     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10476
10477     // Renderpass is started here
10478     BeginCommandBuffer();
10479
10480     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10481     vk_testing::Buffer dstBuffer;
10482     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10483
10484     VkDeviceSize dstOffset = 0;
10485     VkDeviceSize dataSize = 1024;
10486     const void *pData = NULL;
10487
10488     vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData);
10489
10490     m_errorMonitor->VerifyFound();
10491 }
10492
10493 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
10494     // Call CmdClearColorImage within an active RenderPass
10495     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10496                                          "It is invalid to issue this call inside an active render pass");
10497
10498     ASSERT_NO_FATAL_FAILURE(InitState());
10499     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10500
10501     // Renderpass is started here
10502     BeginCommandBuffer();
10503
10504     VkClearColorValue clear_color;
10505     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
10506     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10507     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10508     const int32_t tex_width = 32;
10509     const int32_t tex_height = 32;
10510     VkImageCreateInfo image_create_info = {};
10511     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10512     image_create_info.pNext = NULL;
10513     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10514     image_create_info.format = tex_format;
10515     image_create_info.extent.width = tex_width;
10516     image_create_info.extent.height = tex_height;
10517     image_create_info.extent.depth = 1;
10518     image_create_info.mipLevels = 1;
10519     image_create_info.arrayLayers = 1;
10520     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10521     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
10522     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10523
10524     vk_testing::Image dstImage;
10525     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10526
10527     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
10528
10529     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
10530
10531     m_errorMonitor->VerifyFound();
10532 }
10533
10534 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) {
10535     // Call CmdClearDepthStencilImage within an active RenderPass
10536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10537                                          "It is invalid to issue this call inside an active render pass");
10538
10539     ASSERT_NO_FATAL_FAILURE(InitState());
10540     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10541
10542     // Renderpass is started here
10543     BeginCommandBuffer();
10544
10545     VkClearDepthStencilValue clear_value = {0};
10546     VkMemoryPropertyFlags reqs = 0;
10547     VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
10548     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10549     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
10550     image_create_info.extent.width = 64;
10551     image_create_info.extent.height = 64;
10552     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10553     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
10554
10555     vk_testing::Image dstImage;
10556     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10557
10558     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
10559
10560     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(),
10561                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range);
10562
10563     m_errorMonitor->VerifyFound();
10564 }
10565
10566 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
10567     // Call CmdClearAttachmentss outside of an active RenderPass
10568     VkResult err;
10569
10570     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call "
10571                                                                         "must be issued inside an active "
10572                                                                         "render pass");
10573
10574     ASSERT_NO_FATAL_FAILURE(InitState());
10575     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10576
10577     // Start no RenderPass
10578     err = m_commandBuffer->BeginCommandBuffer();
10579     ASSERT_VK_SUCCESS(err);
10580
10581     VkClearAttachment color_attachment;
10582     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10583     color_attachment.clearValue.color.float32[0] = 0;
10584     color_attachment.clearValue.color.float32[1] = 0;
10585     color_attachment.clearValue.color.float32[2] = 0;
10586     color_attachment.clearValue.color.float32[3] = 0;
10587     color_attachment.colorAttachment = 0;
10588     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
10589     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
10590
10591     m_errorMonitor->VerifyFound();
10592 }
10593
10594 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
10595     TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is "
10596                      "called too many times in a renderpass instance");
10597
10598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance "
10599                                                                         "beyond final subpass");
10600
10601     ASSERT_NO_FATAL_FAILURE(InitState());
10602     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10603
10604     BeginCommandBuffer();
10605
10606     // error here.
10607     vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE);
10608     m_errorMonitor->VerifyFound();
10609
10610     EndCommandBuffer();
10611 }
10612
10613 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
10614     TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is "
10615                      "called before the final subpass has been reached");
10616
10617     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching "
10618                                                                         "final subpass");
10619
10620     ASSERT_NO_FATAL_FAILURE(InitState());
10621     VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
10622                                   {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
10623
10624     VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
10625
10626     VkRenderPass rp;
10627     VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
10628     ASSERT_VK_SUCCESS(err);
10629
10630     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
10631
10632     VkFramebuffer fb;
10633     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
10634     ASSERT_VK_SUCCESS(err);
10635
10636     m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin
10637
10638     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
10639
10640     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
10641
10642     // Error here.
10643     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10644     m_errorMonitor->VerifyFound();
10645
10646     // Clean up.
10647     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
10648     vkDestroyRenderPass(m_device->device(), rp, nullptr);
10649 }
10650
10651 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
10652     // Try to add a buffer memory barrier with no buffer.
10653     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10654                                          "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
10655
10656     ASSERT_NO_FATAL_FAILURE(InitState());
10657     BeginCommandBuffer();
10658
10659     VkBufferMemoryBarrier buf_barrier = {};
10660     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10661     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10662     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10663     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10664     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10665     buf_barrier.buffer = VK_NULL_HANDLE;
10666     buf_barrier.offset = 0;
10667     buf_barrier.size = VK_WHOLE_SIZE;
10668     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10669                          nullptr, 1, &buf_barrier, 0, nullptr);
10670
10671     m_errorMonitor->VerifyFound();
10672 }
10673
10674 TEST_F(VkLayerTest, InvalidBarriers) {
10675     TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
10676
10677     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass");
10678
10679     ASSERT_NO_FATAL_FAILURE(InitState());
10680     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10681
10682     VkMemoryBarrier mem_barrier = {};
10683     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
10684     mem_barrier.pNext = NULL;
10685     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10686     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10687     BeginCommandBuffer();
10688     // BeginCommandBuffer() starts a render pass
10689     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
10690                          &mem_barrier, 0, nullptr, 0, nullptr);
10691     m_errorMonitor->VerifyFound();
10692
10693     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
10694     VkImageObj image(m_device);
10695     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10696     ASSERT_TRUE(image.initialized());
10697     VkImageMemoryBarrier img_barrier = {};
10698     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10699     img_barrier.pNext = NULL;
10700     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10701     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10702     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10703     // New layout can't be UNDEFINED
10704     img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10705     img_barrier.image = image.handle();
10706     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10707     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10708     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10709     img_barrier.subresourceRange.baseArrayLayer = 0;
10710     img_barrier.subresourceRange.baseMipLevel = 0;
10711     img_barrier.subresourceRange.layerCount = 1;
10712     img_barrier.subresourceRange.levelCount = 1;
10713     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10714                          nullptr, 0, nullptr, 1, &img_barrier);
10715     m_errorMonitor->VerifyFound();
10716     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10717
10718     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the "
10719                                                                         "baseArrayLayer");
10720     // baseArrayLayer + layerCount must be <= image's arrayLayers
10721     img_barrier.subresourceRange.baseArrayLayer = 1;
10722     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10723                          nullptr, 0, nullptr, 1, &img_barrier);
10724     m_errorMonitor->VerifyFound();
10725     img_barrier.subresourceRange.baseArrayLayer = 0;
10726
10727     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel");
10728     // baseMipLevel + levelCount must be <= image's mipLevels
10729     img_barrier.subresourceRange.baseMipLevel = 1;
10730     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10731                          nullptr, 0, nullptr, 1, &img_barrier);
10732     m_errorMonitor->VerifyFound();
10733     img_barrier.subresourceRange.baseMipLevel = 0;
10734
10735     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
10736     vk_testing::Buffer buffer;
10737     buffer.init(*m_device, 256);
10738     VkBufferMemoryBarrier buf_barrier = {};
10739     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10740     buf_barrier.pNext = NULL;
10741     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10742     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10743     buf_barrier.buffer = buffer.handle();
10744     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10745     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10746     buf_barrier.offset = 0;
10747     buf_barrier.size = VK_WHOLE_SIZE;
10748     // Can't send buffer barrier during a render pass
10749     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10750                          nullptr, 1, &buf_barrier, 0, nullptr);
10751     m_errorMonitor->VerifyFound();
10752     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10753
10754     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
10755     buf_barrier.offset = 257;
10756     // Offset greater than total size
10757     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10758                          nullptr, 1, &buf_barrier, 0, nullptr);
10759     m_errorMonitor->VerifyFound();
10760     buf_barrier.offset = 0;
10761
10762     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
10763     buf_barrier.size = 257;
10764     // Size greater than total size
10765     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10766                          nullptr, 1, &buf_barrier, 0, nullptr);
10767     m_errorMonitor->VerifyFound();
10768
10769     // Now exercise barrier aspect bit errors, first DS
10770     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must "
10771                                                                         "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
10772                                                                         "VK_IMAGE_ASPECT_STENCIL_BIT set.");
10773     VkDepthStencilObj ds_image(m_device);
10774     ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
10775     ASSERT_TRUE(ds_image.initialized());
10776     img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10777     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10778     img_barrier.image = ds_image.handle();
10779     // Use of COLOR aspect on DS image is error
10780     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10781     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10782                          nullptr, 0, nullptr, 1, &img_barrier);
10783     m_errorMonitor->VerifyFound();
10784     // Now test depth-only
10785     VkFormatProperties format_props;
10786
10787     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
10788     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10789         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must "
10790                                                                             "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
10791         VkDepthStencilObj d_image(m_device);
10792         d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
10793         ASSERT_TRUE(d_image.initialized());
10794         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10795         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10796         img_barrier.image = d_image.handle();
10797         // Use of COLOR aspect on depth image is error
10798         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10799         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10800                              0, nullptr, 0, nullptr, 1, &img_barrier);
10801         m_errorMonitor->VerifyFound();
10802     }
10803     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
10804     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10805         // Now test stencil-only
10806         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must "
10807                                                                             "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
10808         VkDepthStencilObj s_image(m_device);
10809         s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
10810         ASSERT_TRUE(s_image.initialized());
10811         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10812         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10813         img_barrier.image = s_image.handle();
10814         // Use of COLOR aspect on depth image is error
10815         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10816         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10817                              0, nullptr, 0, nullptr, 1, &img_barrier);
10818         m_errorMonitor->VerifyFound();
10819     }
10820     // Finally test color
10821     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
10822                                                                         "have VK_IMAGE_ASPECT_COLOR_BIT set.");
10823     VkImageObj c_image(m_device);
10824     c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10825     ASSERT_TRUE(c_image.initialized());
10826     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10827     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10828     img_barrier.image = c_image.handle();
10829     // Set aspect to depth (non-color)
10830     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
10831     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10832                          nullptr, 0, nullptr, 1, &img_barrier);
10833     m_errorMonitor->VerifyFound();
10834 }
10835
10836 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
10837     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
10838
10839     m_errorMonitor->SetDesiredFailureMsg(
10840         VK_DEBUG_REPORT_WARNING_BIT_EXT,
10841         "must have required access bit");
10842     ASSERT_NO_FATAL_FAILURE(InitState());
10843     VkImageObj image(m_device);
10844     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10845     ASSERT_TRUE(image.initialized());
10846
10847     VkImageMemoryBarrier barrier = {};
10848     VkImageSubresourceRange range;
10849     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10850     barrier.srcAccessMask = 0;
10851     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
10852     barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
10853     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10854     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10855     barrier.image = image.handle();
10856     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10857     range.baseMipLevel = 0;
10858     range.levelCount = 1;
10859     range.baseArrayLayer = 0;
10860     range.layerCount = 1;
10861     barrier.subresourceRange = range;
10862     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
10863     cmdbuf.BeginCommandBuffer();
10864     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10865                            &barrier);
10866     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10867     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10868     barrier.srcAccessMask = 0;
10869     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
10870     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10871                            &barrier);
10872
10873     m_errorMonitor->VerifyFound();
10874 }
10875
10876 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
10877     // Bind a BeginRenderPass within an active RenderPass
10878     VkResult err;
10879
10880     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
10881
10882     ASSERT_NO_FATAL_FAILURE(InitState());
10883     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10884     uint32_t qfi = 0;
10885     VkBufferCreateInfo buffCI = {};
10886     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10887     buffCI.size = 1024;
10888     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10889     buffCI.queueFamilyIndexCount = 1;
10890     buffCI.pQueueFamilyIndices = &qfi;
10891
10892     VkBuffer ib;
10893     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10894     ASSERT_VK_SUCCESS(err);
10895
10896     BeginCommandBuffer();
10897     ASSERT_VK_SUCCESS(err);
10898     // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
10899     // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10900     // Should error before calling to driver so don't care about actual data
10901     vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16);
10902
10903     m_errorMonitor->VerifyFound();
10904
10905     vkDestroyBuffer(m_device->device(), ib, NULL);
10906 }
10907
10908 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
10909     // Create an out-of-range queueFamilyIndex
10910     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10911                                          "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one "
10912                                          "of the indices specified when the device was created, via the "
10913                                          "VkDeviceQueueCreateInfo structure.");
10914
10915     ASSERT_NO_FATAL_FAILURE(InitState());
10916     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10917     VkBufferCreateInfo buffCI = {};
10918     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10919     buffCI.size = 1024;
10920     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10921     buffCI.queueFamilyIndexCount = 1;
10922     // Introduce failure by specifying invalid queue_family_index
10923     uint32_t qfi = 777;
10924     buffCI.pQueueFamilyIndices = &qfi;
10925     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
10926
10927     VkBuffer ib;
10928     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10929
10930     m_errorMonitor->VerifyFound();
10931     vkDestroyBuffer(m_device->device(), ib, NULL);
10932 }
10933
10934 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
10935     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
10936                      " (should only be secondary)");
10937
10938     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
10939
10940     ASSERT_NO_FATAL_FAILURE(InitState());
10941     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10942
10943     BeginCommandBuffer();
10944
10945     VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
10946     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
10947
10948     m_errorMonitor->VerifyFound();
10949 }
10950
10951 TEST_F(VkLayerTest, DSUsageBitsErrors) {
10952     TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
10953                      "that do not have correct usage bits sets.");
10954     VkResult err;
10955
10956     ASSERT_NO_FATAL_FAILURE(InitState());
10957     VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10958     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10959         ds_type_count[i].type = VkDescriptorType(i);
10960         ds_type_count[i].descriptorCount = 1;
10961     }
10962     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10963     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10964     ds_pool_ci.pNext = NULL;
10965     ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10966     ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10967     ds_pool_ci.pPoolSizes = ds_type_count;
10968
10969     VkDescriptorPool ds_pool;
10970     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10971     ASSERT_VK_SUCCESS(err);
10972
10973     // Create 10 layouts where each has a single descriptor of different type
10974     VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10975     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10976         dsl_binding[i].binding = 0;
10977         dsl_binding[i].descriptorType = VkDescriptorType(i);
10978         dsl_binding[i].descriptorCount = 1;
10979         dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
10980         dsl_binding[i].pImmutableSamplers = NULL;
10981     }
10982
10983     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10984     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10985     ds_layout_ci.pNext = NULL;
10986     ds_layout_ci.bindingCount = 1;
10987     VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
10988     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10989         ds_layout_ci.pBindings = dsl_binding + i;
10990         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i);
10991         ASSERT_VK_SUCCESS(err);
10992     }
10993     VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10994     VkDescriptorSetAllocateInfo alloc_info = {};
10995     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10996     alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10997     alloc_info.descriptorPool = ds_pool;
10998     alloc_info.pSetLayouts = ds_layouts;
10999     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
11000     ASSERT_VK_SUCCESS(err);
11001
11002     // Create a buffer & bufferView to be used for invalid updates
11003     VkBufferCreateInfo buff_ci = {};
11004     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11005     // This usage is not valid for any descriptor type
11006     buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
11007     buff_ci.size = 256;
11008     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11009     VkBuffer buffer;
11010     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11011     ASSERT_VK_SUCCESS(err);
11012
11013     VkBufferViewCreateInfo buff_view_ci = {};
11014     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11015     buff_view_ci.buffer = buffer;
11016     buff_view_ci.format = VK_FORMAT_R8_UNORM;
11017     buff_view_ci.range = VK_WHOLE_SIZE;
11018     VkBufferView buff_view;
11019     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11020     ASSERT_VK_SUCCESS(err);
11021
11022     // Create an image to be used for invalid updates
11023     VkImageCreateInfo image_ci = {};
11024     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11025     image_ci.imageType = VK_IMAGE_TYPE_2D;
11026     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11027     image_ci.extent.width = 64;
11028     image_ci.extent.height = 64;
11029     image_ci.extent.depth = 1;
11030     image_ci.mipLevels = 1;
11031     image_ci.arrayLayers = 1;
11032     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11033     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11034     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11035     // This usage is not valid for any descriptor type
11036     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11037     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11038     VkImage image;
11039     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11040     ASSERT_VK_SUCCESS(err);
11041     // Bind memory to image
11042     VkMemoryRequirements mem_reqs;
11043     VkDeviceMemory image_mem;
11044     bool pass;
11045     VkMemoryAllocateInfo mem_alloc = {};
11046     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11047     mem_alloc.pNext = NULL;
11048     mem_alloc.allocationSize = 0;
11049     mem_alloc.memoryTypeIndex = 0;
11050     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11051     mem_alloc.allocationSize = mem_reqs.size;
11052     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11053     ASSERT_TRUE(pass);
11054     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11055     ASSERT_VK_SUCCESS(err);
11056     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11057     ASSERT_VK_SUCCESS(err);
11058     // Now create view for image
11059     VkImageViewCreateInfo image_view_ci = {};
11060     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11061     image_view_ci.image = image;
11062     image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11063     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11064     image_view_ci.subresourceRange.layerCount = 1;
11065     image_view_ci.subresourceRange.baseArrayLayer = 0;
11066     image_view_ci.subresourceRange.levelCount = 1;
11067     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11068     VkImageView image_view;
11069     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11070     ASSERT_VK_SUCCESS(err);
11071
11072     VkDescriptorBufferInfo buff_info = {};
11073     buff_info.buffer = buffer;
11074     VkDescriptorImageInfo img_info = {};
11075     img_info.imageView = image_view;
11076     VkWriteDescriptorSet descriptor_write = {};
11077     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11078     descriptor_write.dstBinding = 0;
11079     descriptor_write.descriptorCount = 1;
11080     descriptor_write.pTexelBufferView = &buff_view;
11081     descriptor_write.pBufferInfo = &buff_info;
11082     descriptor_write.pImageInfo = &img_info;
11083
11084     // These error messages align with VkDescriptorType struct
11085     const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor
11086                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11087                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11088                                 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
11089                                 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
11090                                 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
11091                                 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11092                                 " does not have VK_BUFFER_USAGE_STORAGE_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_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
11096     // Start loop at 1 as SAMPLER desc type has no usage bit error
11097     for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
11098         descriptor_write.descriptorType = VkDescriptorType(i);
11099         descriptor_write.dstSet = descriptor_sets[i];
11100         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]);
11101
11102         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11103
11104         m_errorMonitor->VerifyFound();
11105         vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
11106     }
11107     vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
11108     vkDestroyImage(m_device->device(), image, NULL);
11109     vkFreeMemory(m_device->device(), image_mem, NULL);
11110     vkDestroyImageView(m_device->device(), image_view, NULL);
11111     vkDestroyBuffer(m_device->device(), buffer, NULL);
11112     vkDestroyBufferView(m_device->device(), buff_view, NULL);
11113     vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
11114     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11115 }
11116
11117 TEST_F(VkLayerTest, DSBufferInfoErrors) {
11118     TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect "
11119                      "parameters in VkDescriptorBufferInfo struct. This includes:\n"
11120                      "1. offset value greater than buffer size\n"
11121                      "2. range value of 0\n"
11122                      "3. range value greater than buffer (size - offset)");
11123     VkResult err;
11124
11125     ASSERT_NO_FATAL_FAILURE(InitState());
11126     VkDescriptorPoolSize ds_type_count = {};
11127     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11128     ds_type_count.descriptorCount = 1;
11129
11130     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11131     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11132     ds_pool_ci.pNext = NULL;
11133     ds_pool_ci.maxSets = 1;
11134     ds_pool_ci.poolSizeCount = 1;
11135     ds_pool_ci.pPoolSizes = &ds_type_count;
11136
11137     VkDescriptorPool ds_pool;
11138     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11139     ASSERT_VK_SUCCESS(err);
11140
11141     // Create layout with single uniform buffer descriptor
11142     VkDescriptorSetLayoutBinding dsl_binding = {};
11143     dsl_binding.binding = 0;
11144     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11145     dsl_binding.descriptorCount = 1;
11146     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11147     dsl_binding.pImmutableSamplers = NULL;
11148
11149     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11150     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11151     ds_layout_ci.pNext = NULL;
11152     ds_layout_ci.bindingCount = 1;
11153     ds_layout_ci.pBindings = &dsl_binding;
11154     VkDescriptorSetLayout ds_layout;
11155     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11156     ASSERT_VK_SUCCESS(err);
11157
11158     VkDescriptorSet descriptor_set = {};
11159     VkDescriptorSetAllocateInfo alloc_info = {};
11160     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11161     alloc_info.descriptorSetCount = 1;
11162     alloc_info.descriptorPool = ds_pool;
11163     alloc_info.pSetLayouts = &ds_layout;
11164     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11165     ASSERT_VK_SUCCESS(err);
11166
11167     // Create a buffer to be used for invalid updates
11168     VkBufferCreateInfo buff_ci = {};
11169     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11170     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
11171     buff_ci.size = 256;
11172     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11173     VkBuffer buffer;
11174     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11175     ASSERT_VK_SUCCESS(err);
11176     // Have to bind memory to buffer before descriptor update
11177     VkMemoryAllocateInfo mem_alloc = {};
11178     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11179     mem_alloc.pNext = NULL;
11180     mem_alloc.allocationSize = 256;
11181     mem_alloc.memoryTypeIndex = 0;
11182
11183     VkMemoryRequirements mem_reqs;
11184     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
11185     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11186     if (!pass) {
11187         vkDestroyBuffer(m_device->device(), buffer, NULL);
11188         return;
11189     }
11190
11191     VkDeviceMemory mem;
11192     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
11193     ASSERT_VK_SUCCESS(err);
11194     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
11195     ASSERT_VK_SUCCESS(err);
11196
11197     VkDescriptorBufferInfo buff_info = {};
11198     buff_info.buffer = buffer;
11199     // First make offset 1 larger than buffer size
11200     buff_info.offset = 257;
11201     buff_info.range = VK_WHOLE_SIZE;
11202     VkWriteDescriptorSet descriptor_write = {};
11203     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11204     descriptor_write.dstBinding = 0;
11205     descriptor_write.descriptorCount = 1;
11206     descriptor_write.pTexelBufferView = nullptr;
11207     descriptor_write.pBufferInfo = &buff_info;
11208     descriptor_write.pImageInfo = nullptr;
11209
11210     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11211     descriptor_write.dstSet = descriptor_set;
11212     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer ");
11213
11214     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11215
11216     m_errorMonitor->VerifyFound();
11217     // Now cause error due to range of 0
11218     buff_info.offset = 0;
11219     buff_info.range = 0;
11220     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11221                                          " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
11222
11223     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11224
11225     m_errorMonitor->VerifyFound();
11226     // Now cause error due to range exceeding buffer size - offset
11227     buff_info.offset = 128;
11228     buff_info.range = 200;
11229     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size ");
11230
11231     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11232
11233     m_errorMonitor->VerifyFound();
11234     vkFreeMemory(m_device->device(), mem, NULL);
11235     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11236     vkDestroyBuffer(m_device->device(), buffer, NULL);
11237     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11238     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11239 }
11240
11241 TEST_F(VkLayerTest, DSAspectBitsErrors) {
11242     // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
11243     //  are set, but could expand this test to hit more cases.
11244     TEST_DESCRIPTION("Attempt to update descriptor sets for images "
11245                      "that do not have correct aspect bits sets.");
11246     VkResult err;
11247
11248     ASSERT_NO_FATAL_FAILURE(InitState());
11249     VkDescriptorPoolSize ds_type_count = {};
11250     ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11251     ds_type_count.descriptorCount = 1;
11252
11253     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11254     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11255     ds_pool_ci.pNext = NULL;
11256     ds_pool_ci.maxSets = 5;
11257     ds_pool_ci.poolSizeCount = 1;
11258     ds_pool_ci.pPoolSizes = &ds_type_count;
11259
11260     VkDescriptorPool ds_pool;
11261     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11262     ASSERT_VK_SUCCESS(err);
11263
11264     VkDescriptorSetLayoutBinding dsl_binding = {};
11265     dsl_binding.binding = 0;
11266     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11267     dsl_binding.descriptorCount = 1;
11268     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11269     dsl_binding.pImmutableSamplers = NULL;
11270
11271     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11272     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11273     ds_layout_ci.pNext = NULL;
11274     ds_layout_ci.bindingCount = 1;
11275     ds_layout_ci.pBindings = &dsl_binding;
11276     VkDescriptorSetLayout ds_layout;
11277     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11278     ASSERT_VK_SUCCESS(err);
11279
11280     VkDescriptorSet descriptor_set = {};
11281     VkDescriptorSetAllocateInfo alloc_info = {};
11282     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11283     alloc_info.descriptorSetCount = 1;
11284     alloc_info.descriptorPool = ds_pool;
11285     alloc_info.pSetLayouts = &ds_layout;
11286     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11287     ASSERT_VK_SUCCESS(err);
11288
11289     // Create an image to be used for invalid updates
11290     VkImageCreateInfo image_ci = {};
11291     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11292     image_ci.imageType = VK_IMAGE_TYPE_2D;
11293     image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11294     image_ci.extent.width = 64;
11295     image_ci.extent.height = 64;
11296     image_ci.extent.depth = 1;
11297     image_ci.mipLevels = 1;
11298     image_ci.arrayLayers = 1;
11299     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11300     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11301     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11302     image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11303     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11304     VkImage image;
11305     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11306     ASSERT_VK_SUCCESS(err);
11307     // Bind memory to image
11308     VkMemoryRequirements mem_reqs;
11309     VkDeviceMemory image_mem;
11310     bool pass;
11311     VkMemoryAllocateInfo mem_alloc = {};
11312     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11313     mem_alloc.pNext = NULL;
11314     mem_alloc.allocationSize = 0;
11315     mem_alloc.memoryTypeIndex = 0;
11316     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11317     mem_alloc.allocationSize = mem_reqs.size;
11318     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11319     ASSERT_TRUE(pass);
11320     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11321     ASSERT_VK_SUCCESS(err);
11322     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11323     ASSERT_VK_SUCCESS(err);
11324     // Now create view for image
11325     VkImageViewCreateInfo image_view_ci = {};
11326     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11327     image_view_ci.image = image;
11328     image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11329     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11330     image_view_ci.subresourceRange.layerCount = 1;
11331     image_view_ci.subresourceRange.baseArrayLayer = 0;
11332     image_view_ci.subresourceRange.levelCount = 1;
11333     // Setting both depth & stencil aspect bits is illegal for descriptor
11334     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
11335
11336     VkImageView image_view;
11337     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11338     ASSERT_VK_SUCCESS(err);
11339
11340     VkDescriptorImageInfo img_info = {};
11341     img_info.imageView = image_view;
11342     VkWriteDescriptorSet descriptor_write = {};
11343     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11344     descriptor_write.dstBinding = 0;
11345     descriptor_write.descriptorCount = 1;
11346     descriptor_write.pTexelBufferView = NULL;
11347     descriptor_write.pBufferInfo = NULL;
11348     descriptor_write.pImageInfo = &img_info;
11349     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11350     descriptor_write.dstSet = descriptor_set;
11351     const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
11352                             "or VK_IMAGE_ASPECT_STENCIL_BIT ";
11353     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
11354
11355     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11356
11357     m_errorMonitor->VerifyFound();
11358     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11359     vkDestroyImage(m_device->device(), image, NULL);
11360     vkFreeMemory(m_device->device(), image_mem, NULL);
11361     vkDestroyImageView(m_device->device(), image_view, NULL);
11362     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11363     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11364 }
11365
11366 TEST_F(VkLayerTest, DSTypeMismatch) {
11367     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
11368     VkResult err;
11369
11370     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11371                                          " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update "
11372                                          "type is VK_DESCRIPTOR_TYPE_SAMPLER");
11373
11374     ASSERT_NO_FATAL_FAILURE(InitState());
11375     // VkDescriptorSetObj descriptorSet(m_device);
11376     VkDescriptorPoolSize ds_type_count = {};
11377     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11378     ds_type_count.descriptorCount = 1;
11379
11380     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11381     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11382     ds_pool_ci.pNext = NULL;
11383     ds_pool_ci.maxSets = 1;
11384     ds_pool_ci.poolSizeCount = 1;
11385     ds_pool_ci.pPoolSizes = &ds_type_count;
11386
11387     VkDescriptorPool ds_pool;
11388     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11389     ASSERT_VK_SUCCESS(err);
11390     VkDescriptorSetLayoutBinding dsl_binding = {};
11391     dsl_binding.binding = 0;
11392     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11393     dsl_binding.descriptorCount = 1;
11394     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11395     dsl_binding.pImmutableSamplers = NULL;
11396
11397     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11398     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11399     ds_layout_ci.pNext = NULL;
11400     ds_layout_ci.bindingCount = 1;
11401     ds_layout_ci.pBindings = &dsl_binding;
11402
11403     VkDescriptorSetLayout ds_layout;
11404     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11405     ASSERT_VK_SUCCESS(err);
11406
11407     VkDescriptorSet descriptorSet;
11408     VkDescriptorSetAllocateInfo alloc_info = {};
11409     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11410     alloc_info.descriptorSetCount = 1;
11411     alloc_info.descriptorPool = ds_pool;
11412     alloc_info.pSetLayouts = &ds_layout;
11413     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11414     ASSERT_VK_SUCCESS(err);
11415
11416     VkSamplerCreateInfo sampler_ci = {};
11417     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11418     sampler_ci.pNext = NULL;
11419     sampler_ci.magFilter = VK_FILTER_NEAREST;
11420     sampler_ci.minFilter = VK_FILTER_NEAREST;
11421     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11422     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11423     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11424     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11425     sampler_ci.mipLodBias = 1.0;
11426     sampler_ci.anisotropyEnable = VK_FALSE;
11427     sampler_ci.maxAnisotropy = 1;
11428     sampler_ci.compareEnable = VK_FALSE;
11429     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11430     sampler_ci.minLod = 1.0;
11431     sampler_ci.maxLod = 1.0;
11432     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11433     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11434     VkSampler sampler;
11435     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11436     ASSERT_VK_SUCCESS(err);
11437
11438     VkDescriptorImageInfo info = {};
11439     info.sampler = sampler;
11440
11441     VkWriteDescriptorSet descriptor_write;
11442     memset(&descriptor_write, 0, sizeof(descriptor_write));
11443     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11444     descriptor_write.dstSet = descriptorSet;
11445     descriptor_write.descriptorCount = 1;
11446     // This is a mismatched type for the layout which expects BUFFER
11447     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11448     descriptor_write.pImageInfo = &info;
11449
11450     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11451
11452     m_errorMonitor->VerifyFound();
11453
11454     vkDestroySampler(m_device->device(), sampler, NULL);
11455     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11456     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11457 }
11458
11459 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
11460     // For overlapping Update, have arrayIndex exceed that of layout
11461     VkResult err;
11462
11463     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11464                                          " binding #0 with 1 total descriptors but update of 1 descriptors "
11465                                          "starting at binding offset of 0 combined with update array element "
11466                                          "offset of 1 oversteps the size of this descriptor set.");
11467
11468     ASSERT_NO_FATAL_FAILURE(InitState());
11469     // VkDescriptorSetObj descriptorSet(m_device);
11470     VkDescriptorPoolSize ds_type_count = {};
11471     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11472     ds_type_count.descriptorCount = 1;
11473
11474     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11475     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11476     ds_pool_ci.pNext = NULL;
11477     ds_pool_ci.maxSets = 1;
11478     ds_pool_ci.poolSizeCount = 1;
11479     ds_pool_ci.pPoolSizes = &ds_type_count;
11480
11481     VkDescriptorPool ds_pool;
11482     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11483     ASSERT_VK_SUCCESS(err);
11484
11485     VkDescriptorSetLayoutBinding dsl_binding = {};
11486     dsl_binding.binding = 0;
11487     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11488     dsl_binding.descriptorCount = 1;
11489     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11490     dsl_binding.pImmutableSamplers = NULL;
11491
11492     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11493     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11494     ds_layout_ci.pNext = NULL;
11495     ds_layout_ci.bindingCount = 1;
11496     ds_layout_ci.pBindings = &dsl_binding;
11497
11498     VkDescriptorSetLayout ds_layout;
11499     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11500     ASSERT_VK_SUCCESS(err);
11501
11502     VkDescriptorSet descriptorSet;
11503     VkDescriptorSetAllocateInfo alloc_info = {};
11504     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11505     alloc_info.descriptorSetCount = 1;
11506     alloc_info.descriptorPool = ds_pool;
11507     alloc_info.pSetLayouts = &ds_layout;
11508     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11509     ASSERT_VK_SUCCESS(err);
11510
11511     // Correctly update descriptor to avoid "NOT_UPDATED" error
11512     VkDescriptorBufferInfo buff_info = {};
11513     buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test
11514     buff_info.offset = 0;
11515     buff_info.range = 1024;
11516
11517     VkWriteDescriptorSet descriptor_write;
11518     memset(&descriptor_write, 0, sizeof(descriptor_write));
11519     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11520     descriptor_write.dstSet = descriptorSet;
11521     descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
11522     descriptor_write.descriptorCount = 1;
11523     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11524     descriptor_write.pBufferInfo = &buff_info;
11525
11526     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11527
11528     m_errorMonitor->VerifyFound();
11529
11530     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11531     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11532 }
11533
11534 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
11535     // Create layout w/ count of 1 and attempt update to that layout w/ binding
11536     // index 2
11537     VkResult err;
11538
11539     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2.");
11540
11541     ASSERT_NO_FATAL_FAILURE(InitState());
11542     // VkDescriptorSetObj descriptorSet(m_device);
11543     VkDescriptorPoolSize ds_type_count = {};
11544     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11545     ds_type_count.descriptorCount = 1;
11546
11547     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11548     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11549     ds_pool_ci.pNext = NULL;
11550     ds_pool_ci.maxSets = 1;
11551     ds_pool_ci.poolSizeCount = 1;
11552     ds_pool_ci.pPoolSizes = &ds_type_count;
11553
11554     VkDescriptorPool ds_pool;
11555     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11556     ASSERT_VK_SUCCESS(err);
11557
11558     VkDescriptorSetLayoutBinding dsl_binding = {};
11559     dsl_binding.binding = 0;
11560     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11561     dsl_binding.descriptorCount = 1;
11562     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11563     dsl_binding.pImmutableSamplers = NULL;
11564
11565     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11566     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11567     ds_layout_ci.pNext = NULL;
11568     ds_layout_ci.bindingCount = 1;
11569     ds_layout_ci.pBindings = &dsl_binding;
11570     VkDescriptorSetLayout ds_layout;
11571     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11572     ASSERT_VK_SUCCESS(err);
11573
11574     VkDescriptorSet descriptorSet;
11575     VkDescriptorSetAllocateInfo alloc_info = {};
11576     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11577     alloc_info.descriptorSetCount = 1;
11578     alloc_info.descriptorPool = ds_pool;
11579     alloc_info.pSetLayouts = &ds_layout;
11580     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11581     ASSERT_VK_SUCCESS(err);
11582
11583     VkSamplerCreateInfo sampler_ci = {};
11584     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11585     sampler_ci.pNext = NULL;
11586     sampler_ci.magFilter = VK_FILTER_NEAREST;
11587     sampler_ci.minFilter = VK_FILTER_NEAREST;
11588     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11589     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11590     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11591     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11592     sampler_ci.mipLodBias = 1.0;
11593     sampler_ci.anisotropyEnable = VK_FALSE;
11594     sampler_ci.maxAnisotropy = 1;
11595     sampler_ci.compareEnable = VK_FALSE;
11596     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11597     sampler_ci.minLod = 1.0;
11598     sampler_ci.maxLod = 1.0;
11599     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11600     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11601
11602     VkSampler sampler;
11603     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11604     ASSERT_VK_SUCCESS(err);
11605
11606     VkDescriptorImageInfo info = {};
11607     info.sampler = sampler;
11608
11609     VkWriteDescriptorSet descriptor_write;
11610     memset(&descriptor_write, 0, sizeof(descriptor_write));
11611     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11612     descriptor_write.dstSet = descriptorSet;
11613     descriptor_write.dstBinding = 2;
11614     descriptor_write.descriptorCount = 1;
11615     // This is the wrong type, but out of bounds will be flagged first
11616     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11617     descriptor_write.pImageInfo = &info;
11618
11619     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11620
11621     m_errorMonitor->VerifyFound();
11622
11623     vkDestroySampler(m_device->device(), sampler, NULL);
11624     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11625     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11626 }
11627
11628 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
11629     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
11630     // types
11631     VkResult err;
11632
11633     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
11634
11635     ASSERT_NO_FATAL_FAILURE(InitState());
11636
11637     VkDescriptorPoolSize ds_type_count = {};
11638     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11639     ds_type_count.descriptorCount = 1;
11640
11641     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11642     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11643     ds_pool_ci.pNext = NULL;
11644     ds_pool_ci.maxSets = 1;
11645     ds_pool_ci.poolSizeCount = 1;
11646     ds_pool_ci.pPoolSizes = &ds_type_count;
11647
11648     VkDescriptorPool ds_pool;
11649     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11650     ASSERT_VK_SUCCESS(err);
11651     VkDescriptorSetLayoutBinding dsl_binding = {};
11652     dsl_binding.binding = 0;
11653     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11654     dsl_binding.descriptorCount = 1;
11655     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11656     dsl_binding.pImmutableSamplers = NULL;
11657
11658     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11659     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11660     ds_layout_ci.pNext = NULL;
11661     ds_layout_ci.bindingCount = 1;
11662     ds_layout_ci.pBindings = &dsl_binding;
11663
11664     VkDescriptorSetLayout ds_layout;
11665     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11666     ASSERT_VK_SUCCESS(err);
11667
11668     VkDescriptorSet descriptorSet;
11669     VkDescriptorSetAllocateInfo alloc_info = {};
11670     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11671     alloc_info.descriptorSetCount = 1;
11672     alloc_info.descriptorPool = ds_pool;
11673     alloc_info.pSetLayouts = &ds_layout;
11674     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11675     ASSERT_VK_SUCCESS(err);
11676
11677     VkSamplerCreateInfo sampler_ci = {};
11678     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11679     sampler_ci.pNext = NULL;
11680     sampler_ci.magFilter = VK_FILTER_NEAREST;
11681     sampler_ci.minFilter = VK_FILTER_NEAREST;
11682     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11683     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11684     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11685     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11686     sampler_ci.mipLodBias = 1.0;
11687     sampler_ci.anisotropyEnable = VK_FALSE;
11688     sampler_ci.maxAnisotropy = 1;
11689     sampler_ci.compareEnable = VK_FALSE;
11690     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11691     sampler_ci.minLod = 1.0;
11692     sampler_ci.maxLod = 1.0;
11693     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11694     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11695     VkSampler sampler;
11696     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11697     ASSERT_VK_SUCCESS(err);
11698
11699     VkDescriptorImageInfo info = {};
11700     info.sampler = sampler;
11701
11702     VkWriteDescriptorSet descriptor_write;
11703     memset(&descriptor_write, 0, sizeof(descriptor_write));
11704     descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
11705     descriptor_write.dstSet = descriptorSet;
11706     descriptor_write.descriptorCount = 1;
11707     // This is the wrong type, but out of bounds will be flagged first
11708     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11709     descriptor_write.pImageInfo = &info;
11710
11711     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11712
11713     m_errorMonitor->VerifyFound();
11714
11715     vkDestroySampler(m_device->device(), sampler, NULL);
11716     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11717     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11718 }
11719
11720 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
11721     // Create a single Sampler descriptor and send it an invalid Sampler
11722     VkResult err;
11723
11724     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11725                                          "Attempted write update to sampler descriptor with invalid sampler");
11726
11727     ASSERT_NO_FATAL_FAILURE(InitState());
11728     // TODO : Farm Descriptor setup code to helper function(s) to reduce copied
11729     // code
11730     VkDescriptorPoolSize ds_type_count = {};
11731     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
11732     ds_type_count.descriptorCount = 1;
11733
11734     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11735     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11736     ds_pool_ci.pNext = NULL;
11737     ds_pool_ci.maxSets = 1;
11738     ds_pool_ci.poolSizeCount = 1;
11739     ds_pool_ci.pPoolSizes = &ds_type_count;
11740
11741     VkDescriptorPool ds_pool;
11742     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11743     ASSERT_VK_SUCCESS(err);
11744
11745     VkDescriptorSetLayoutBinding dsl_binding = {};
11746     dsl_binding.binding = 0;
11747     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11748     dsl_binding.descriptorCount = 1;
11749     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11750     dsl_binding.pImmutableSamplers = NULL;
11751
11752     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11753     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11754     ds_layout_ci.pNext = NULL;
11755     ds_layout_ci.bindingCount = 1;
11756     ds_layout_ci.pBindings = &dsl_binding;
11757     VkDescriptorSetLayout ds_layout;
11758     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11759     ASSERT_VK_SUCCESS(err);
11760
11761     VkDescriptorSet descriptorSet;
11762     VkDescriptorSetAllocateInfo alloc_info = {};
11763     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11764     alloc_info.descriptorSetCount = 1;
11765     alloc_info.descriptorPool = ds_pool;
11766     alloc_info.pSetLayouts = &ds_layout;
11767     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11768     ASSERT_VK_SUCCESS(err);
11769
11770     VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle
11771
11772     VkDescriptorImageInfo descriptor_info;
11773     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11774     descriptor_info.sampler = sampler;
11775
11776     VkWriteDescriptorSet descriptor_write;
11777     memset(&descriptor_write, 0, sizeof(descriptor_write));
11778     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11779     descriptor_write.dstSet = descriptorSet;
11780     descriptor_write.dstBinding = 0;
11781     descriptor_write.descriptorCount = 1;
11782     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11783     descriptor_write.pImageInfo = &descriptor_info;
11784
11785     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11786
11787     m_errorMonitor->VerifyFound();
11788
11789     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11790     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11791 }
11792
11793 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
11794     // Create a single combined Image/Sampler descriptor and send it an invalid
11795     // imageView
11796     VkResult err;
11797
11798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined "
11799                                                                         "image sampler descriptor failed due "
11800                                                                         "to: Invalid VkImageView:");
11801
11802     ASSERT_NO_FATAL_FAILURE(InitState());
11803     VkDescriptorPoolSize ds_type_count = {};
11804     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11805     ds_type_count.descriptorCount = 1;
11806
11807     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11808     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11809     ds_pool_ci.pNext = NULL;
11810     ds_pool_ci.maxSets = 1;
11811     ds_pool_ci.poolSizeCount = 1;
11812     ds_pool_ci.pPoolSizes = &ds_type_count;
11813
11814     VkDescriptorPool ds_pool;
11815     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11816     ASSERT_VK_SUCCESS(err);
11817
11818     VkDescriptorSetLayoutBinding dsl_binding = {};
11819     dsl_binding.binding = 0;
11820     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11821     dsl_binding.descriptorCount = 1;
11822     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11823     dsl_binding.pImmutableSamplers = NULL;
11824
11825     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11826     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11827     ds_layout_ci.pNext = NULL;
11828     ds_layout_ci.bindingCount = 1;
11829     ds_layout_ci.pBindings = &dsl_binding;
11830     VkDescriptorSetLayout ds_layout;
11831     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11832     ASSERT_VK_SUCCESS(err);
11833
11834     VkDescriptorSet descriptorSet;
11835     VkDescriptorSetAllocateInfo alloc_info = {};
11836     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11837     alloc_info.descriptorSetCount = 1;
11838     alloc_info.descriptorPool = ds_pool;
11839     alloc_info.pSetLayouts = &ds_layout;
11840     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11841     ASSERT_VK_SUCCESS(err);
11842
11843     VkSamplerCreateInfo sampler_ci = {};
11844     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11845     sampler_ci.pNext = NULL;
11846     sampler_ci.magFilter = VK_FILTER_NEAREST;
11847     sampler_ci.minFilter = VK_FILTER_NEAREST;
11848     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11849     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11850     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11851     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11852     sampler_ci.mipLodBias = 1.0;
11853     sampler_ci.anisotropyEnable = VK_FALSE;
11854     sampler_ci.maxAnisotropy = 1;
11855     sampler_ci.compareEnable = VK_FALSE;
11856     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11857     sampler_ci.minLod = 1.0;
11858     sampler_ci.maxLod = 1.0;
11859     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11860     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11861
11862     VkSampler sampler;
11863     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11864     ASSERT_VK_SUCCESS(err);
11865
11866     VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object
11867
11868     VkDescriptorImageInfo descriptor_info;
11869     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11870     descriptor_info.sampler = sampler;
11871     descriptor_info.imageView = view;
11872
11873     VkWriteDescriptorSet descriptor_write;
11874     memset(&descriptor_write, 0, sizeof(descriptor_write));
11875     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11876     descriptor_write.dstSet = descriptorSet;
11877     descriptor_write.dstBinding = 0;
11878     descriptor_write.descriptorCount = 1;
11879     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11880     descriptor_write.pImageInfo = &descriptor_info;
11881
11882     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11883
11884     m_errorMonitor->VerifyFound();
11885
11886     vkDestroySampler(m_device->device(), sampler, NULL);
11887     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11888     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11889 }
11890
11891 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
11892     // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
11893     // into the other
11894     VkResult err;
11895
11896     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type "
11897                                                                         "VK_DESCRIPTOR_TYPE_SAMPLER. Types do "
11898                                                                         "not match.");
11899
11900     ASSERT_NO_FATAL_FAILURE(InitState());
11901     // VkDescriptorSetObj descriptorSet(m_device);
11902     VkDescriptorPoolSize ds_type_count[2] = {};
11903     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11904     ds_type_count[0].descriptorCount = 1;
11905     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
11906     ds_type_count[1].descriptorCount = 1;
11907
11908     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11909     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11910     ds_pool_ci.pNext = NULL;
11911     ds_pool_ci.maxSets = 1;
11912     ds_pool_ci.poolSizeCount = 2;
11913     ds_pool_ci.pPoolSizes = ds_type_count;
11914
11915     VkDescriptorPool ds_pool;
11916     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11917     ASSERT_VK_SUCCESS(err);
11918     VkDescriptorSetLayoutBinding dsl_binding[2] = {};
11919     dsl_binding[0].binding = 0;
11920     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11921     dsl_binding[0].descriptorCount = 1;
11922     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
11923     dsl_binding[0].pImmutableSamplers = NULL;
11924     dsl_binding[1].binding = 1;
11925     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11926     dsl_binding[1].descriptorCount = 1;
11927     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
11928     dsl_binding[1].pImmutableSamplers = NULL;
11929
11930     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11931     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11932     ds_layout_ci.pNext = NULL;
11933     ds_layout_ci.bindingCount = 2;
11934     ds_layout_ci.pBindings = dsl_binding;
11935
11936     VkDescriptorSetLayout ds_layout;
11937     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11938     ASSERT_VK_SUCCESS(err);
11939
11940     VkDescriptorSet descriptorSet;
11941     VkDescriptorSetAllocateInfo alloc_info = {};
11942     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11943     alloc_info.descriptorSetCount = 1;
11944     alloc_info.descriptorPool = ds_pool;
11945     alloc_info.pSetLayouts = &ds_layout;
11946     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11947     ASSERT_VK_SUCCESS(err);
11948
11949     VkSamplerCreateInfo sampler_ci = {};
11950     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11951     sampler_ci.pNext = NULL;
11952     sampler_ci.magFilter = VK_FILTER_NEAREST;
11953     sampler_ci.minFilter = VK_FILTER_NEAREST;
11954     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11955     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11956     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11957     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11958     sampler_ci.mipLodBias = 1.0;
11959     sampler_ci.anisotropyEnable = VK_FALSE;
11960     sampler_ci.maxAnisotropy = 1;
11961     sampler_ci.compareEnable = VK_FALSE;
11962     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11963     sampler_ci.minLod = 1.0;
11964     sampler_ci.maxLod = 1.0;
11965     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11966     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11967
11968     VkSampler sampler;
11969     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11970     ASSERT_VK_SUCCESS(err);
11971
11972     VkDescriptorImageInfo info = {};
11973     info.sampler = sampler;
11974
11975     VkWriteDescriptorSet descriptor_write;
11976     memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
11977     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11978     descriptor_write.dstSet = descriptorSet;
11979     descriptor_write.dstBinding = 1; // SAMPLER binding from layout above
11980     descriptor_write.descriptorCount = 1;
11981     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11982     descriptor_write.pImageInfo = &info;
11983     // This write update should succeed
11984     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11985     // Now perform a copy update that fails due to type mismatch
11986     VkCopyDescriptorSet copy_ds_update;
11987     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
11988     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
11989     copy_ds_update.srcSet = descriptorSet;
11990     copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding
11991     copy_ds_update.dstSet = descriptorSet;
11992     copy_ds_update.dstBinding = 0;      // ERROR : copy to UNIFORM binding
11993     copy_ds_update.descriptorCount = 1; // copy 1 descriptor
11994     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
11995
11996     m_errorMonitor->VerifyFound();
11997     // Now perform a copy update that fails due to binding out of bounds
11998     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
11999     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12000     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12001     copy_ds_update.srcSet = descriptorSet;
12002     copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout
12003     copy_ds_update.dstSet = descriptorSet;
12004     copy_ds_update.dstBinding = 0;
12005     copy_ds_update.descriptorCount = 1; // Copy 1 descriptor
12006     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12007
12008     m_errorMonitor->VerifyFound();
12009
12010     // Now perform a copy update that fails due to binding out of bounds
12011     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus "
12012                                                                         "update array offset of 0 and update of "
12013                                                                         "5 descriptors oversteps total number "
12014                                                                         "of descriptors in set: 2.");
12015
12016     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12017     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12018     copy_ds_update.srcSet = descriptorSet;
12019     copy_ds_update.srcBinding = 1;
12020     copy_ds_update.dstSet = descriptorSet;
12021     copy_ds_update.dstBinding = 0;
12022     copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout)
12023     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12024
12025     m_errorMonitor->VerifyFound();
12026
12027     vkDestroySampler(m_device->device(), sampler, NULL);
12028     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12029     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12030 }
12031
12032 TEST_F(VkLayerTest, NumSamplesMismatch) {
12033     // Create CommandBuffer where MSAA samples doesn't match RenderPass
12034     // sampleCount
12035     VkResult err;
12036
12037     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
12038
12039     ASSERT_NO_FATAL_FAILURE(InitState());
12040     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12041     VkDescriptorPoolSize ds_type_count = {};
12042     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12043     ds_type_count.descriptorCount = 1;
12044
12045     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12046     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12047     ds_pool_ci.pNext = NULL;
12048     ds_pool_ci.maxSets = 1;
12049     ds_pool_ci.poolSizeCount = 1;
12050     ds_pool_ci.pPoolSizes = &ds_type_count;
12051
12052     VkDescriptorPool ds_pool;
12053     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12054     ASSERT_VK_SUCCESS(err);
12055
12056     VkDescriptorSetLayoutBinding dsl_binding = {};
12057     dsl_binding.binding = 0;
12058     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12059     dsl_binding.descriptorCount = 1;
12060     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12061     dsl_binding.pImmutableSamplers = NULL;
12062
12063     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12064     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12065     ds_layout_ci.pNext = NULL;
12066     ds_layout_ci.bindingCount = 1;
12067     ds_layout_ci.pBindings = &dsl_binding;
12068
12069     VkDescriptorSetLayout ds_layout;
12070     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12071     ASSERT_VK_SUCCESS(err);
12072
12073     VkDescriptorSet descriptorSet;
12074     VkDescriptorSetAllocateInfo alloc_info = {};
12075     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12076     alloc_info.descriptorSetCount = 1;
12077     alloc_info.descriptorPool = ds_pool;
12078     alloc_info.pSetLayouts = &ds_layout;
12079     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12080     ASSERT_VK_SUCCESS(err);
12081
12082     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12083     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12084     pipe_ms_state_ci.pNext = NULL;
12085     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12086     pipe_ms_state_ci.sampleShadingEnable = 0;
12087     pipe_ms_state_ci.minSampleShading = 1.0;
12088     pipe_ms_state_ci.pSampleMask = NULL;
12089
12090     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12091     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12092     pipeline_layout_ci.pNext = NULL;
12093     pipeline_layout_ci.setLayoutCount = 1;
12094     pipeline_layout_ci.pSetLayouts = &ds_layout;
12095
12096     VkPipelineLayout pipeline_layout;
12097     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12098     ASSERT_VK_SUCCESS(err);
12099
12100     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12101     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12102     // but add it to be able to run on more devices
12103     VkPipelineObj pipe(m_device);
12104     pipe.AddShader(&vs);
12105     pipe.AddShader(&fs);
12106     pipe.AddColorAttachment();
12107     pipe.SetMSAA(&pipe_ms_state_ci);
12108     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12109
12110     BeginCommandBuffer();
12111     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12112
12113     // Render triangle (the error should trigger on the attempt to draw).
12114     Draw(3, 1, 0, 0);
12115
12116     // Finalize recording of the command buffer
12117     EndCommandBuffer();
12118
12119     m_errorMonitor->VerifyFound();
12120
12121     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12122     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12123     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12124 }
12125
12126 TEST_F(VkLayerTest, RenderPassIncompatible) {
12127     TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
12128                      "Initial case is drawing with an active renderpass that's "
12129                      "not compatible with the bound PSO's creation renderpass");
12130     VkResult err;
12131
12132     ASSERT_NO_FATAL_FAILURE(InitState());
12133     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12134
12135     VkDescriptorSetLayoutBinding dsl_binding = {};
12136     dsl_binding.binding = 0;
12137     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12138     dsl_binding.descriptorCount = 1;
12139     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12140     dsl_binding.pImmutableSamplers = NULL;
12141
12142     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12143     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12144     ds_layout_ci.pNext = NULL;
12145     ds_layout_ci.bindingCount = 1;
12146     ds_layout_ci.pBindings = &dsl_binding;
12147
12148     VkDescriptorSetLayout ds_layout;
12149     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12150     ASSERT_VK_SUCCESS(err);
12151
12152     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12153     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12154     pipeline_layout_ci.pNext = NULL;
12155     pipeline_layout_ci.setLayoutCount = 1;
12156     pipeline_layout_ci.pSetLayouts = &ds_layout;
12157
12158     VkPipelineLayout pipeline_layout;
12159     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12160     ASSERT_VK_SUCCESS(err);
12161
12162     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12163     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12164     // but add it to be able to run on more devices
12165     // Create a renderpass that will be incompatible with default renderpass
12166     VkAttachmentReference attach = {};
12167     attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12168     VkAttachmentReference color_att = {};
12169     color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12170     VkSubpassDescription subpass = {};
12171     subpass.inputAttachmentCount = 1;
12172     subpass.pInputAttachments = &attach;
12173     subpass.colorAttachmentCount = 1;
12174     subpass.pColorAttachments = &color_att;
12175     VkRenderPassCreateInfo rpci = {};
12176     rpci.subpassCount = 1;
12177     rpci.pSubpasses = &subpass;
12178     rpci.attachmentCount = 1;
12179     VkAttachmentDescription attach_desc = {};
12180     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12181     // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
12182     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
12183     rpci.pAttachments = &attach_desc;
12184     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12185     VkRenderPass rp;
12186     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12187     VkPipelineObj pipe(m_device);
12188     pipe.AddShader(&vs);
12189     pipe.AddShader(&fs);
12190     pipe.AddColorAttachment();
12191     VkViewport view_port = {};
12192     m_viewports.push_back(view_port);
12193     pipe.SetViewport(m_viewports);
12194     VkRect2D rect = {};
12195     m_scissors.push_back(rect);
12196     pipe.SetScissor(m_scissors);
12197     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12198
12199     VkCommandBufferInheritanceInfo cbii = {};
12200     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12201     cbii.renderPass = rp;
12202     cbii.subpass = 0;
12203     VkCommandBufferBeginInfo cbbi = {};
12204     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12205     cbbi.pInheritanceInfo = &cbii;
12206     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
12207     VkRenderPassBeginInfo rpbi = {};
12208     rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
12209     rpbi.framebuffer = m_framebuffer;
12210     rpbi.renderPass = rp;
12211     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
12212     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12213
12214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline ");
12215     // Render triangle (the error should trigger on the attempt to draw).
12216     Draw(3, 1, 0, 0);
12217
12218     // Finalize recording of the command buffer
12219     EndCommandBuffer();
12220
12221     m_errorMonitor->VerifyFound();
12222
12223     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12224     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12225     vkDestroyRenderPass(m_device->device(), rp, NULL);
12226 }
12227
12228 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
12229     // Create Pipeline where the number of blend attachments doesn't match the
12230     // number of color attachments.  In this case, we don't add any color
12231     // blend attachments even though we have a color attachment.
12232     VkResult err;
12233
12234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12235                                          "Render pass subpass 0 mismatch with blending state defined and blend state attachment");
12236
12237     ASSERT_NO_FATAL_FAILURE(InitState());
12238     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12239     VkDescriptorPoolSize ds_type_count = {};
12240     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12241     ds_type_count.descriptorCount = 1;
12242
12243     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12244     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12245     ds_pool_ci.pNext = NULL;
12246     ds_pool_ci.maxSets = 1;
12247     ds_pool_ci.poolSizeCount = 1;
12248     ds_pool_ci.pPoolSizes = &ds_type_count;
12249
12250     VkDescriptorPool ds_pool;
12251     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12252     ASSERT_VK_SUCCESS(err);
12253
12254     VkDescriptorSetLayoutBinding dsl_binding = {};
12255     dsl_binding.binding = 0;
12256     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12257     dsl_binding.descriptorCount = 1;
12258     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12259     dsl_binding.pImmutableSamplers = NULL;
12260
12261     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12262     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12263     ds_layout_ci.pNext = NULL;
12264     ds_layout_ci.bindingCount = 1;
12265     ds_layout_ci.pBindings = &dsl_binding;
12266
12267     VkDescriptorSetLayout ds_layout;
12268     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12269     ASSERT_VK_SUCCESS(err);
12270
12271     VkDescriptorSet descriptorSet;
12272     VkDescriptorSetAllocateInfo alloc_info = {};
12273     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12274     alloc_info.descriptorSetCount = 1;
12275     alloc_info.descriptorPool = ds_pool;
12276     alloc_info.pSetLayouts = &ds_layout;
12277     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12278     ASSERT_VK_SUCCESS(err);
12279
12280     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12281     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12282     pipe_ms_state_ci.pNext = NULL;
12283     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12284     pipe_ms_state_ci.sampleShadingEnable = 0;
12285     pipe_ms_state_ci.minSampleShading = 1.0;
12286     pipe_ms_state_ci.pSampleMask = NULL;
12287
12288     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12289     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12290     pipeline_layout_ci.pNext = NULL;
12291     pipeline_layout_ci.setLayoutCount = 1;
12292     pipeline_layout_ci.pSetLayouts = &ds_layout;
12293
12294     VkPipelineLayout pipeline_layout;
12295     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12296     ASSERT_VK_SUCCESS(err);
12297
12298     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12299     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12300     // but add it to be able to run on more devices
12301     VkPipelineObj pipe(m_device);
12302     pipe.AddShader(&vs);
12303     pipe.AddShader(&fs);
12304     pipe.SetMSAA(&pipe_ms_state_ci);
12305     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12306
12307     BeginCommandBuffer();
12308     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12309
12310     // Render triangle (the error should trigger on the attempt to draw).
12311     Draw(3, 1, 0, 0);
12312
12313     // Finalize recording of the command buffer
12314     EndCommandBuffer();
12315
12316     m_errorMonitor->VerifyFound();
12317
12318     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12319     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12320     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12321 }
12322
12323 TEST_F(VkLayerTest, MissingClearAttachment) {
12324     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
12325                      "structure passed to vkCmdClearAttachments");
12326     ASSERT_NO_FATAL_FAILURE(InitState());
12327     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12328                                          "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored");
12329
12330     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
12331     m_errorMonitor->VerifyFound();
12332 }
12333
12334 TEST_F(VkLayerTest, ClearCmdNoDraw) {
12335     // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
12336     // to issuing a Draw
12337     VkResult err;
12338
12339     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12340                                          "vkCmdClearAttachments() issued on CB object ");
12341
12342     ASSERT_NO_FATAL_FAILURE(InitState());
12343     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12344
12345     VkDescriptorPoolSize ds_type_count = {};
12346     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12347     ds_type_count.descriptorCount = 1;
12348
12349     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12350     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12351     ds_pool_ci.pNext = NULL;
12352     ds_pool_ci.maxSets = 1;
12353     ds_pool_ci.poolSizeCount = 1;
12354     ds_pool_ci.pPoolSizes = &ds_type_count;
12355
12356     VkDescriptorPool ds_pool;
12357     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12358     ASSERT_VK_SUCCESS(err);
12359
12360     VkDescriptorSetLayoutBinding dsl_binding = {};
12361     dsl_binding.binding = 0;
12362     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12363     dsl_binding.descriptorCount = 1;
12364     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12365     dsl_binding.pImmutableSamplers = NULL;
12366
12367     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12368     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12369     ds_layout_ci.pNext = NULL;
12370     ds_layout_ci.bindingCount = 1;
12371     ds_layout_ci.pBindings = &dsl_binding;
12372
12373     VkDescriptorSetLayout ds_layout;
12374     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12375     ASSERT_VK_SUCCESS(err);
12376
12377     VkDescriptorSet descriptorSet;
12378     VkDescriptorSetAllocateInfo alloc_info = {};
12379     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12380     alloc_info.descriptorSetCount = 1;
12381     alloc_info.descriptorPool = ds_pool;
12382     alloc_info.pSetLayouts = &ds_layout;
12383     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12384     ASSERT_VK_SUCCESS(err);
12385
12386     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12387     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12388     pipe_ms_state_ci.pNext = NULL;
12389     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12390     pipe_ms_state_ci.sampleShadingEnable = 0;
12391     pipe_ms_state_ci.minSampleShading = 1.0;
12392     pipe_ms_state_ci.pSampleMask = NULL;
12393
12394     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12395     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12396     pipeline_layout_ci.pNext = NULL;
12397     pipeline_layout_ci.setLayoutCount = 1;
12398     pipeline_layout_ci.pSetLayouts = &ds_layout;
12399
12400     VkPipelineLayout pipeline_layout;
12401     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12402     ASSERT_VK_SUCCESS(err);
12403
12404     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12405     //  We shouldn't need a fragment shader but add it to be able to run
12406     //  on more devices
12407     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12408
12409     VkPipelineObj pipe(m_device);
12410     pipe.AddShader(&vs);
12411     pipe.AddShader(&fs);
12412     pipe.SetMSAA(&pipe_ms_state_ci);
12413     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12414
12415     BeginCommandBuffer();
12416
12417     // Main thing we care about for this test is that the VkImage obj we're
12418     // clearing matches Color Attachment of FB
12419     //  Also pass down other dummy params to keep driver and paramchecker happy
12420     VkClearAttachment color_attachment;
12421     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12422     color_attachment.clearValue.color.float32[0] = 1.0;
12423     color_attachment.clearValue.color.float32[1] = 1.0;
12424     color_attachment.clearValue.color.float32[2] = 1.0;
12425     color_attachment.clearValue.color.float32[3] = 1.0;
12426     color_attachment.colorAttachment = 0;
12427     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}};
12428
12429     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
12430
12431     m_errorMonitor->VerifyFound();
12432
12433     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12434     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12435     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12436 }
12437
12438 TEST_F(VkLayerTest, VtxBufferBadIndex) {
12439     VkResult err;
12440
12441     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12442                                          "but no vertex buffers are attached to this Pipeline State Object");
12443
12444     ASSERT_NO_FATAL_FAILURE(InitState());
12445     ASSERT_NO_FATAL_FAILURE(InitViewport());
12446     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12447
12448     VkDescriptorPoolSize ds_type_count = {};
12449     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12450     ds_type_count.descriptorCount = 1;
12451
12452     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12453     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12454     ds_pool_ci.pNext = NULL;
12455     ds_pool_ci.maxSets = 1;
12456     ds_pool_ci.poolSizeCount = 1;
12457     ds_pool_ci.pPoolSizes = &ds_type_count;
12458
12459     VkDescriptorPool ds_pool;
12460     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12461     ASSERT_VK_SUCCESS(err);
12462
12463     VkDescriptorSetLayoutBinding dsl_binding = {};
12464     dsl_binding.binding = 0;
12465     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12466     dsl_binding.descriptorCount = 1;
12467     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12468     dsl_binding.pImmutableSamplers = NULL;
12469
12470     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12471     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12472     ds_layout_ci.pNext = NULL;
12473     ds_layout_ci.bindingCount = 1;
12474     ds_layout_ci.pBindings = &dsl_binding;
12475
12476     VkDescriptorSetLayout ds_layout;
12477     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12478     ASSERT_VK_SUCCESS(err);
12479
12480     VkDescriptorSet descriptorSet;
12481     VkDescriptorSetAllocateInfo alloc_info = {};
12482     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12483     alloc_info.descriptorSetCount = 1;
12484     alloc_info.descriptorPool = ds_pool;
12485     alloc_info.pSetLayouts = &ds_layout;
12486     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12487     ASSERT_VK_SUCCESS(err);
12488
12489     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12490     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12491     pipe_ms_state_ci.pNext = NULL;
12492     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12493     pipe_ms_state_ci.sampleShadingEnable = 0;
12494     pipe_ms_state_ci.minSampleShading = 1.0;
12495     pipe_ms_state_ci.pSampleMask = NULL;
12496
12497     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12498     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12499     pipeline_layout_ci.pNext = NULL;
12500     pipeline_layout_ci.setLayoutCount = 1;
12501     pipeline_layout_ci.pSetLayouts = &ds_layout;
12502     VkPipelineLayout pipeline_layout;
12503
12504     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12505     ASSERT_VK_SUCCESS(err);
12506
12507     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12508     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12509     // but add it to be able to run on more devices
12510     VkPipelineObj pipe(m_device);
12511     pipe.AddShader(&vs);
12512     pipe.AddShader(&fs);
12513     pipe.AddColorAttachment();
12514     pipe.SetMSAA(&pipe_ms_state_ci);
12515     pipe.SetViewport(m_viewports);
12516     pipe.SetScissor(m_scissors);
12517     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12518
12519     BeginCommandBuffer();
12520     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12521     // Don't care about actual data, just need to get to draw to flag error
12522     static const float vbo_data[3] = {1.f, 0.f, 1.f};
12523     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data);
12524     BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
12525     Draw(1, 0, 0, 0);
12526
12527     m_errorMonitor->VerifyFound();
12528
12529     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12530     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12531     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12532 }
12533
12534 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
12535     TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call."
12536                      "Use invalid Queue Family Index in vkCreateDevice");
12537     ASSERT_NO_FATAL_FAILURE(InitState());
12538
12539     const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() "
12540                                          "w/ pPhysicalDeviceCount value ";
12541
12542     const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid "
12543                                                    "queueFamilyIndex ";
12544
12545     const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #";
12546
12547     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message);
12548     // The following test fails with recent NVidia drivers.
12549     // By the time core_validation is reached, the NVidia
12550     // driver has sanitized the invalid condition and core_validation
12551     // is not introduced to the failure condition. This is not the case
12552     // with AMD and Mesa drivers. Futher investigation is required
12553     //    uint32_t count = static_cast<uint32_t>(~0);
12554     //    VkPhysicalDevice physical_device;
12555     //    vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
12556     //    m_errorMonitor->VerifyFound();
12557
12558     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message);
12559     float queue_priority = 0.0;
12560
12561     VkDeviceQueueCreateInfo queue_create_info = {};
12562     queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
12563     queue_create_info.queueCount = 1;
12564     queue_create_info.pQueuePriorities = &queue_priority;
12565     queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
12566
12567     VkPhysicalDeviceFeatures features = m_device->phy().features();
12568     VkDevice testDevice;
12569     VkDeviceCreateInfo device_create_info = {};
12570     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
12571     device_create_info.queueCreateInfoCount = 1;
12572     device_create_info.pQueueCreateInfos = &queue_create_info;
12573     device_create_info.pEnabledFeatures = &features;
12574     vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12575     m_errorMonitor->VerifyFound();
12576
12577     queue_create_info.queueFamilyIndex = 1;
12578
12579     unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
12580     VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
12581     for (unsigned i = 0; i < feature_count; i++) {
12582         if (VK_FALSE == feature_array[i]) {
12583             feature_array[i] = VK_TRUE;
12584             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message);
12585             device_create_info.pEnabledFeatures = &features;
12586             vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12587             m_errorMonitor->VerifyFound();
12588             break;
12589         }
12590     }
12591 }
12592
12593 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) {
12594     TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call."
12595                      "End a command buffer with a query still in progress.");
12596
12597     const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one "
12598                                       "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both "
12599                                       "must be.";
12600
12601     const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
12602
12603     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index);
12604
12605     ASSERT_NO_FATAL_FAILURE(InitState());
12606
12607     VkEvent event;
12608     VkEventCreateInfo event_create_info{};
12609     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12610     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12611
12612     VkQueue queue = VK_NULL_HANDLE;
12613     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
12614
12615     BeginCommandBuffer();
12616
12617     VkImageObj image(m_device);
12618     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12619     ASSERT_TRUE(image.initialized());
12620     VkImageMemoryBarrier img_barrier = {};
12621     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
12622     img_barrier.pNext = NULL;
12623     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
12624     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
12625     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12626     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12627     img_barrier.image = image.handle();
12628     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
12629
12630     // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies
12631     // that layer validation catches the case when it is not.
12632     img_barrier.dstQueueFamilyIndex = 0;
12633     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12634     img_barrier.subresourceRange.baseArrayLayer = 0;
12635     img_barrier.subresourceRange.baseMipLevel = 0;
12636     img_barrier.subresourceRange.layerCount = 1;
12637     img_barrier.subresourceRange.levelCount = 1;
12638     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
12639                     nullptr, 0, nullptr, 1, &img_barrier);
12640     m_errorMonitor->VerifyFound();
12641
12642     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
12643
12644     VkQueryPool query_pool;
12645     VkQueryPoolCreateInfo query_pool_create_info = {};
12646     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
12647     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
12648     query_pool_create_info.queryCount = 1;
12649     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12650
12651     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
12652     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12653
12654     vkEndCommandBuffer(m_commandBuffer->handle());
12655     m_errorMonitor->VerifyFound();
12656
12657     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
12658     vkDestroyEvent(m_device->device(), event, nullptr);
12659 }
12660
12661 TEST_F(VkLayerTest, VertexBufferInvalid) {
12662     TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
12663                      "delete a buffer twice, use an invalid offset for each "
12664                      "buffer type, and attempt to bind a null buffer");
12665
12666     const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
12667                                                    "using deleted buffer ";
12668     const char *double_destroy_message = "Cannot free buffer 0x";
12669     const char *invalid_offset_message = "vkBindBufferMemory(): "
12670                                          "memoryOffset is 0x";
12671     const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
12672                                                         "storage memoryOffset "
12673                                                         "is 0x";
12674     const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
12675                                                       "texel memoryOffset "
12676                                                       "is 0x";
12677     const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
12678                                                         "uniform memoryOffset "
12679                                                         "is 0x";
12680     const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
12681                                            " to Bind Obj(0x";
12682     const char *free_invalid_buffer_message = "Request to delete memory "
12683                                               "object 0x";
12684
12685     ASSERT_NO_FATAL_FAILURE(InitState());
12686     ASSERT_NO_FATAL_FAILURE(InitViewport());
12687     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12688
12689     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12690     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12691     pipe_ms_state_ci.pNext = NULL;
12692     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12693     pipe_ms_state_ci.sampleShadingEnable = 0;
12694     pipe_ms_state_ci.minSampleShading = 1.0;
12695     pipe_ms_state_ci.pSampleMask = nullptr;
12696
12697     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12698     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12699     VkPipelineLayout pipeline_layout;
12700
12701     VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout);
12702     ASSERT_VK_SUCCESS(err);
12703
12704     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12705     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12706     VkPipelineObj pipe(m_device);
12707     pipe.AddShader(&vs);
12708     pipe.AddShader(&fs);
12709     pipe.AddColorAttachment();
12710     pipe.SetMSAA(&pipe_ms_state_ci);
12711     pipe.SetViewport(m_viewports);
12712     pipe.SetScissor(m_scissors);
12713     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12714
12715     BeginCommandBuffer();
12716     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12717
12718     {
12719         // Create and bind a vertex buffer in a reduced scope, which will cause
12720         // it to be deleted upon leaving this scope
12721         const float vbo_data[3] = {1.f, 0.f, 1.f};
12722         VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data);
12723         draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
12724         draw_verticies.AddVertexInputToPipe(pipe);
12725     }
12726
12727     Draw(1, 0, 0, 0);
12728
12729     EndCommandBuffer();
12730
12731     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
12732     QueueCommandBuffer(false);
12733     m_errorMonitor->VerifyFound();
12734
12735     {
12736         // Create and bind a vertex buffer in a reduced scope, and delete it
12737         // twice, the second through the destructor
12738         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
12739         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message);
12740         buffer_test.TestDoubleDestroy();
12741     }
12742     m_errorMonitor->VerifyFound();
12743
12744     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
12745         // Create and bind a memory buffer with an invalid offset.
12746         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
12747         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
12748         (void)buffer_test;
12749         m_errorMonitor->VerifyFound();
12750     }
12751
12752     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
12753                                             VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
12754         // Create and bind a memory buffer with an invalid offset again,
12755         // but look for a texel buffer message.
12756         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
12757         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12758         (void)buffer_test;
12759         m_errorMonitor->VerifyFound();
12760     }
12761
12762     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
12763         // Create and bind a memory buffer with an invalid offset again, but
12764         // look for a uniform buffer message.
12765         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
12766         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12767         (void)buffer_test;
12768         m_errorMonitor->VerifyFound();
12769     }
12770
12771     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
12772         // Create and bind a memory buffer with an invalid offset again, but
12773         // look for a storage buffer message.
12774         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
12775         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12776         (void)buffer_test;
12777         m_errorMonitor->VerifyFound();
12778     }
12779
12780     {
12781         // Attempt to bind a null buffer.
12782         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message);
12783         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer);
12784         (void)buffer_test;
12785         m_errorMonitor->VerifyFound();
12786     }
12787
12788     {
12789         // Attempt to use an invalid handle to delete a buffer.
12790         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message);
12791         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
12792         (void)buffer_test;
12793     }
12794     m_errorMonitor->VerifyFound();
12795
12796     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12797 }
12798
12799 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
12800 TEST_F(VkLayerTest, InvalidImageLayout) {
12801     TEST_DESCRIPTION("Hit all possible validation checks associated with the "
12802                      "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having"
12803                      "images in the wrong layout when they're copied or transitioned.");
12804     // 3 in ValidateCmdBufImageLayouts
12805     // *  -1 Attempt to submit cmd buf w/ deleted image
12806     // *  -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
12807     // *  -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
12808     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12809                                          "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
12810
12811     ASSERT_NO_FATAL_FAILURE(InitState());
12812     // Create src & dst images to use for copy operations
12813     VkImage src_image;
12814     VkImage dst_image;
12815
12816     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
12817     const int32_t tex_width = 32;
12818     const int32_t tex_height = 32;
12819
12820     VkImageCreateInfo image_create_info = {};
12821     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
12822     image_create_info.pNext = NULL;
12823     image_create_info.imageType = VK_IMAGE_TYPE_2D;
12824     image_create_info.format = tex_format;
12825     image_create_info.extent.width = tex_width;
12826     image_create_info.extent.height = tex_height;
12827     image_create_info.extent.depth = 1;
12828     image_create_info.mipLevels = 1;
12829     image_create_info.arrayLayers = 4;
12830     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
12831     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
12832     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
12833     image_create_info.flags = 0;
12834
12835     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
12836     ASSERT_VK_SUCCESS(err);
12837     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
12838     ASSERT_VK_SUCCESS(err);
12839
12840     BeginCommandBuffer();
12841     VkImageCopy copyRegion;
12842     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12843     copyRegion.srcSubresource.mipLevel = 0;
12844     copyRegion.srcSubresource.baseArrayLayer = 0;
12845     copyRegion.srcSubresource.layerCount = 1;
12846     copyRegion.srcOffset.x = 0;
12847     copyRegion.srcOffset.y = 0;
12848     copyRegion.srcOffset.z = 0;
12849     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12850     copyRegion.dstSubresource.mipLevel = 0;
12851     copyRegion.dstSubresource.baseArrayLayer = 0;
12852     copyRegion.dstSubresource.layerCount = 1;
12853     copyRegion.dstOffset.x = 0;
12854     copyRegion.dstOffset.y = 0;
12855     copyRegion.dstOffset.z = 0;
12856     copyRegion.extent.width = 1;
12857     copyRegion.extent.height = 1;
12858     copyRegion.extent.depth = 1;
12859     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12860     m_errorMonitor->VerifyFound();
12861     // Now cause error due to src image layout changing
12862     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is "
12863                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12864                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12865     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12866     m_errorMonitor->VerifyFound();
12867     // Final src error is due to bad layout type
12868     m_errorMonitor->SetDesiredFailureMsg(
12869         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12870         "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL.");
12871     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12872     m_errorMonitor->VerifyFound();
12873     // Now verify same checks for dst
12874     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12875                                          "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
12876     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12877     m_errorMonitor->VerifyFound();
12878     // Now cause error due to src image layout changing
12879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is "
12880                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12881                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12882     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12883     m_errorMonitor->VerifyFound();
12884     m_errorMonitor->SetDesiredFailureMsg(
12885         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12886         "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL.");
12887     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12888     m_errorMonitor->VerifyFound();
12889     // Now cause error due to bad image layout transition in PipelineBarrier
12890     VkImageMemoryBarrier image_barrier[1] = {};
12891     image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12892     image_barrier[0].image = src_image;
12893     image_barrier[0].subresourceRange.layerCount = 2;
12894     image_barrier[0].subresourceRange.levelCount = 2;
12895     image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12896     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from "
12897                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when "
12898                                                                         "current layout is VK_IMAGE_LAYOUT_GENERAL.");
12899     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
12900                          NULL, 0, NULL, 1, image_barrier);
12901     m_errorMonitor->VerifyFound();
12902
12903     // Finally some layout errors at RenderPass create time
12904     // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
12905     VkAttachmentReference attach = {};
12906     // perf warning for GENERAL layout w/ non-DS input attachment
12907     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12908     VkSubpassDescription subpass = {};
12909     subpass.inputAttachmentCount = 1;
12910     subpass.pInputAttachments = &attach;
12911     VkRenderPassCreateInfo rpci = {};
12912     rpci.subpassCount = 1;
12913     rpci.pSubpasses = &subpass;
12914     rpci.attachmentCount = 1;
12915     VkAttachmentDescription attach_desc = {};
12916     attach_desc.format = VK_FORMAT_UNDEFINED;
12917     rpci.pAttachments = &attach_desc;
12918     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12919     VkRenderPass rp;
12920     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12921                                          "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
12922     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12923     m_errorMonitor->VerifyFound();
12924     // error w/ non-general layout
12925     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12926
12927     m_errorMonitor->SetDesiredFailureMsg(
12928         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12929         "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
12930     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12931     m_errorMonitor->VerifyFound();
12932     subpass.inputAttachmentCount = 0;
12933     subpass.colorAttachmentCount = 1;
12934     subpass.pColorAttachments = &attach;
12935     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12936     // perf warning for GENERAL layout on color attachment
12937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12938                                          "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
12939     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12940     m_errorMonitor->VerifyFound();
12941     // error w/ non-color opt or GENERAL layout for color attachment
12942     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12943     m_errorMonitor->SetDesiredFailureMsg(
12944         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12945         "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
12946     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12947     m_errorMonitor->VerifyFound();
12948     subpass.colorAttachmentCount = 0;
12949     subpass.pDepthStencilAttachment = &attach;
12950     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12951     // perf warning for GENERAL layout on DS attachment
12952     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12953                                          "GENERAL layout for depth attachment may not give optimal performance.");
12954     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12955     m_errorMonitor->VerifyFound();
12956     // error w/ non-ds opt or GENERAL layout for color attachment
12957     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12958     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12959                                          "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
12960                                          "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
12961     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12962     m_errorMonitor->VerifyFound();
12963     // For this error we need a valid renderpass so create default one
12964     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12965     attach.attachment = 0;
12966     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
12967     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12968     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
12969     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
12970     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
12971     // Can't do a CLEAR load on READ_ONLY initialLayout
12972     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
12973     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12974     attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12975     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout "
12976                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_"
12977                                                                         "ONLY_OPTIMAL");
12978     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12979     m_errorMonitor->VerifyFound();
12980
12981     vkDestroyImage(m_device->device(), src_image, NULL);
12982     vkDestroyImage(m_device->device(), dst_image, NULL);
12983 }
12984
12985 TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
12986     TEST_DESCRIPTION("Positive test where we create a renderpass with an "
12987                      "attachment that uses LOAD_OP_CLEAR, the first subpass "
12988                      "has a valid layout, and a second subpass then uses a "
12989                      "valid *READ_ONLY* layout.");
12990     m_errorMonitor->ExpectSuccess();
12991     ASSERT_NO_FATAL_FAILURE(InitState());
12992
12993     VkAttachmentReference attach[2] = {};
12994     attach[0].attachment = 0;
12995     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
12996     attach[1].attachment = 0;
12997     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12998     VkSubpassDescription subpasses[2] = {};
12999     // First subpass clears DS attach on load
13000     subpasses[0].pDepthStencilAttachment = &attach[0];
13001     // 2nd subpass reads in DS as input attachment
13002     subpasses[1].inputAttachmentCount = 1;
13003     subpasses[1].pInputAttachments = &attach[1];
13004     VkAttachmentDescription attach_desc = {};
13005     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
13006     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
13007     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
13008     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
13009     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13010     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13011     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13012     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13013     VkRenderPassCreateInfo rpci = {};
13014     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
13015     rpci.attachmentCount = 1;
13016     rpci.pAttachments = &attach_desc;
13017     rpci.subpassCount = 2;
13018     rpci.pSubpasses = subpasses;
13019
13020     // Now create RenderPass and verify no errors
13021     VkRenderPass rp;
13022     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
13023     m_errorMonitor->VerifyNotFound();
13024
13025     vkDestroyRenderPass(m_device->device(), rp, NULL);
13026 }
13027
13028 TEST_F(VkLayerTest, SimultaneousUse) {
13029     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13030                      "in primary and secondary command buffers.");
13031
13032     ASSERT_NO_FATAL_FAILURE(InitState());
13033     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13034
13035     const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
13036     const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
13037                                             "will cause primary command buffer";
13038
13039     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
13040     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13041     command_buffer_allocate_info.commandPool = m_commandPool;
13042     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13043     command_buffer_allocate_info.commandBufferCount = 1;
13044
13045     VkCommandBuffer secondary_command_buffer;
13046     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
13047     VkCommandBufferBeginInfo command_buffer_begin_info = {};
13048     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
13049     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
13050     command_buffer_inheritance_info.renderPass = m_renderPass;
13051     command_buffer_inheritance_info.framebuffer = m_framebuffer;
13052     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13053     command_buffer_begin_info.flags =
13054         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13055     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
13056
13057     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
13058     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13059     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13060     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13061     vkEndCommandBuffer(secondary_command_buffer);
13062
13063     VkSubmitInfo submit_info = {};
13064     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13065     submit_info.commandBufferCount = 1;
13066     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13067     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13068
13069     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13070     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13071     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1);
13072     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13073     m_errorMonitor->VerifyFound();
13074     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13075     vkEndCommandBuffer(m_commandBuffer->handle());
13076
13077     m_errorMonitor->SetDesiredFailureMsg(0, "");
13078     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13079
13080     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
13081     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13082     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13083
13084     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2);
13085     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13086     m_errorMonitor->VerifyFound();
13087     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13088     vkEndCommandBuffer(m_commandBuffer->handle());
13089 }
13090
13091 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
13092     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13093                      "in primary and secondary command buffers. "
13094                      "Delete objects that are inuse. Call VkQueueSubmit "
13095                      "with an event that has been deleted.");
13096
13097     ASSERT_NO_FATAL_FAILURE(InitState());
13098     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13099
13100     const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x";
13101     const char *cannot_delete_event_message = "Cannot delete event 0x";
13102     const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x";
13103     const char *cannot_destroy_fence_message = "Fence 0x";
13104
13105     BeginCommandBuffer();
13106
13107     VkEvent event;
13108     VkEventCreateInfo event_create_info = {};
13109     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
13110     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13111     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13112
13113     EndCommandBuffer();
13114     vkDestroyEvent(m_device->device(), event, nullptr);
13115
13116     VkSubmitInfo submit_info = {};
13117     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13118     submit_info.commandBufferCount = 1;
13119     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13120     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message);
13121     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13122     m_errorMonitor->VerifyFound();
13123
13124     m_errorMonitor->SetDesiredFailureMsg(0, "");
13125     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13126
13127     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13128
13129     VkSemaphoreCreateInfo semaphore_create_info = {};
13130     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13131     VkSemaphore semaphore;
13132     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13133     VkFenceCreateInfo fence_create_info = {};
13134     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13135     VkFence fence;
13136     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13137
13138     VkDescriptorPoolSize descriptor_pool_type_count = {};
13139     descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13140     descriptor_pool_type_count.descriptorCount = 1;
13141
13142     VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
13143     descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13144     descriptor_pool_create_info.maxSets = 1;
13145     descriptor_pool_create_info.poolSizeCount = 1;
13146     descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
13147     descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
13148
13149     VkDescriptorPool descriptorset_pool;
13150     ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
13151
13152     VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
13153     descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13154     descriptorset_layout_binding.descriptorCount = 1;
13155     descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
13156
13157     VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
13158     descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13159     descriptorset_layout_create_info.bindingCount = 1;
13160     descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
13161
13162     VkDescriptorSetLayout descriptorset_layout;
13163     ASSERT_VK_SUCCESS(
13164         vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
13165
13166     VkDescriptorSet descriptorset;
13167     VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
13168     descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13169     descriptorset_allocate_info.descriptorSetCount = 1;
13170     descriptorset_allocate_info.descriptorPool = descriptorset_pool;
13171     descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
13172     ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
13173
13174     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
13175
13176     VkDescriptorBufferInfo buffer_info = {};
13177     buffer_info.buffer = buffer_test.GetBuffer();
13178     buffer_info.offset = 0;
13179     buffer_info.range = 1024;
13180
13181     VkWriteDescriptorSet write_descriptor_set = {};
13182     write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13183     write_descriptor_set.dstSet = descriptorset;
13184     write_descriptor_set.descriptorCount = 1;
13185     write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13186     write_descriptor_set.pBufferInfo = &buffer_info;
13187
13188     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
13189
13190     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13191     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13192
13193     VkPipelineObj pipe(m_device);
13194     pipe.AddColorAttachment();
13195     pipe.AddShader(&vs);
13196     pipe.AddShader(&fs);
13197
13198     VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
13199     pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13200     pipeline_layout_create_info.setLayoutCount = 1;
13201     pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
13202
13203     VkPipelineLayout pipeline_layout;
13204     ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
13205
13206     pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
13207
13208     BeginCommandBuffer();
13209     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13210
13211     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13212     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13213                             &descriptorset, 0, NULL);
13214
13215     EndCommandBuffer();
13216
13217     submit_info.signalSemaphoreCount = 1;
13218     submit_info.pSignalSemaphores = &semaphore;
13219     vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
13220
13221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message);
13222     vkDestroyEvent(m_device->device(), event, nullptr);
13223     m_errorMonitor->VerifyFound();
13224
13225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message);
13226     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13227     m_errorMonitor->VerifyFound();
13228
13229     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message);
13230     vkDestroyFence(m_device->device(), fence, nullptr);
13231     m_errorMonitor->VerifyFound();
13232
13233     vkQueueWaitIdle(m_device->m_queue);
13234     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13235     vkDestroyFence(m_device->device(), fence, nullptr);
13236     vkDestroyEvent(m_device->device(), event, nullptr);
13237     vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
13238     vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
13239     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
13240 }
13241
13242 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
13243     TEST_DESCRIPTION("Delete in-use query pool.");
13244
13245     ASSERT_NO_FATAL_FAILURE(InitState());
13246     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13247
13248     VkQueryPool query_pool;
13249     VkQueryPoolCreateInfo query_pool_ci{};
13250     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
13251     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
13252     query_pool_ci.queryCount = 1;
13253     vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13254     BeginCommandBuffer();
13255     // Reset query pool to create binding with cmd buffer
13256     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13257
13258     EndCommandBuffer();
13259
13260     VkSubmitInfo submit_info = {};
13261     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13262     submit_info.commandBufferCount = 1;
13263     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13264     // Submit cmd buffer and then destroy query pool while in-flight
13265     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13266
13267     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x");
13268     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13269     m_errorMonitor->VerifyFound();
13270
13271     vkQueueWaitIdle(m_device->m_queue);
13272     // Now that cmd buffer done we can safely destroy query_pool
13273     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13274 }
13275
13276 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
13277     TEST_DESCRIPTION("Delete in-use pipeline.");
13278
13279     ASSERT_NO_FATAL_FAILURE(InitState());
13280     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13281
13282     // Empty pipeline layout used for binding PSO
13283     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13284     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13285     pipeline_layout_ci.setLayoutCount = 0;
13286     pipeline_layout_ci.pSetLayouts = NULL;
13287
13288     VkPipelineLayout pipeline_layout;
13289     VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout);
13290     ASSERT_VK_SUCCESS(err);
13291
13292     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x");
13293     // Create PSO to be used for draw-time errors below
13294     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13295     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13296     // Store pipeline handle so we can actually delete it before test finishes
13297     VkPipeline delete_this_pipeline;
13298     { // Scope pipeline so it will be auto-deleted
13299         VkPipelineObj pipe(m_device);
13300         pipe.AddShader(&vs);
13301         pipe.AddShader(&fs);
13302         pipe.AddColorAttachment();
13303         pipe.CreateVKPipeline(pipeline_layout, renderPass());
13304         delete_this_pipeline = pipe.handle();
13305
13306         BeginCommandBuffer();
13307         // Bind pipeline to cmd buffer
13308         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13309
13310         EndCommandBuffer();
13311
13312         VkSubmitInfo submit_info = {};
13313         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13314         submit_info.commandBufferCount = 1;
13315         submit_info.pCommandBuffers = &m_commandBuffer->handle();
13316         // Submit cmd buffer and then pipeline destroyed while in-flight
13317         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13318     } // Pipeline deletion triggered here
13319     m_errorMonitor->VerifyFound();
13320     // Make sure queue finished and then actually delete pipeline
13321     vkQueueWaitIdle(m_device->m_queue);
13322     vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
13323     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
13324 }
13325
13326 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
13327     TEST_DESCRIPTION("Delete in-use imageView.");
13328
13329     ASSERT_NO_FATAL_FAILURE(InitState());
13330     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13331
13332     VkDescriptorPoolSize ds_type_count;
13333     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13334     ds_type_count.descriptorCount = 1;
13335
13336     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13337     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13338     ds_pool_ci.maxSets = 1;
13339     ds_pool_ci.poolSizeCount = 1;
13340     ds_pool_ci.pPoolSizes = &ds_type_count;
13341
13342     VkDescriptorPool ds_pool;
13343     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13344     ASSERT_VK_SUCCESS(err);
13345
13346     VkSamplerCreateInfo sampler_ci = {};
13347     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13348     sampler_ci.pNext = NULL;
13349     sampler_ci.magFilter = VK_FILTER_NEAREST;
13350     sampler_ci.minFilter = VK_FILTER_NEAREST;
13351     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13352     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13353     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13354     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13355     sampler_ci.mipLodBias = 1.0;
13356     sampler_ci.anisotropyEnable = VK_FALSE;
13357     sampler_ci.maxAnisotropy = 1;
13358     sampler_ci.compareEnable = VK_FALSE;
13359     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13360     sampler_ci.minLod = 1.0;
13361     sampler_ci.maxLod = 1.0;
13362     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13363     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13364     VkSampler sampler;
13365
13366     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13367     ASSERT_VK_SUCCESS(err);
13368
13369     VkDescriptorSetLayoutBinding layout_binding;
13370     layout_binding.binding = 0;
13371     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13372     layout_binding.descriptorCount = 1;
13373     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13374     layout_binding.pImmutableSamplers = NULL;
13375
13376     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13377     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13378     ds_layout_ci.bindingCount = 1;
13379     ds_layout_ci.pBindings = &layout_binding;
13380     VkDescriptorSetLayout ds_layout;
13381     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13382     ASSERT_VK_SUCCESS(err);
13383
13384     VkDescriptorSetAllocateInfo alloc_info = {};
13385     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13386     alloc_info.descriptorSetCount = 1;
13387     alloc_info.descriptorPool = ds_pool;
13388     alloc_info.pSetLayouts = &ds_layout;
13389     VkDescriptorSet descriptor_set;
13390     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13391     ASSERT_VK_SUCCESS(err);
13392
13393     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13394     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13395     pipeline_layout_ci.pNext = NULL;
13396     pipeline_layout_ci.setLayoutCount = 1;
13397     pipeline_layout_ci.pSetLayouts = &ds_layout;
13398
13399     VkPipelineLayout pipeline_layout;
13400     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13401     ASSERT_VK_SUCCESS(err);
13402
13403     VkImageObj image(m_device);
13404     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13405     ASSERT_TRUE(image.initialized());
13406
13407     VkImageView view;
13408     VkImageViewCreateInfo ivci = {};
13409     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13410     ivci.image = image.handle();
13411     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13412     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13413     ivci.subresourceRange.layerCount = 1;
13414     ivci.subresourceRange.baseMipLevel = 0;
13415     ivci.subresourceRange.levelCount = 1;
13416     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13417
13418     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13419     ASSERT_VK_SUCCESS(err);
13420
13421     VkDescriptorImageInfo image_info{};
13422     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13423     image_info.imageView = view;
13424     image_info.sampler = sampler;
13425
13426     VkWriteDescriptorSet descriptor_write = {};
13427     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13428     descriptor_write.dstSet = descriptor_set;
13429     descriptor_write.dstBinding = 0;
13430     descriptor_write.descriptorCount = 1;
13431     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13432     descriptor_write.pImageInfo = &image_info;
13433
13434     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13435
13436     // Create PSO to use the sampler
13437     char const *vsSource = "#version 450\n"
13438                            "\n"
13439                            "out gl_PerVertex { \n"
13440                            "    vec4 gl_Position;\n"
13441                            "};\n"
13442                            "void main(){\n"
13443                            "   gl_Position = vec4(1);\n"
13444                            "}\n";
13445     char const *fsSource = "#version 450\n"
13446                            "\n"
13447                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13448                            "layout(location=0) out vec4 x;\n"
13449                            "void main(){\n"
13450                            "   x = texture(s, vec2(1));\n"
13451                            "}\n";
13452     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13453     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13454     VkPipelineObj pipe(m_device);
13455     pipe.AddShader(&vs);
13456     pipe.AddShader(&fs);
13457     pipe.AddColorAttachment();
13458     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13459
13460     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
13461
13462     BeginCommandBuffer();
13463     // Bind pipeline to cmd buffer
13464     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13465     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13466                             &descriptor_set, 0, nullptr);
13467     Draw(1, 0, 0, 0);
13468     EndCommandBuffer();
13469     // Submit cmd buffer then destroy sampler
13470     VkSubmitInfo submit_info = {};
13471     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13472     submit_info.commandBufferCount = 1;
13473     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13474     // Submit cmd buffer and then destroy imageView while in-flight
13475     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13476
13477     vkDestroyImageView(m_device->device(), view, nullptr);
13478     m_errorMonitor->VerifyFound();
13479     vkQueueWaitIdle(m_device->m_queue);
13480     // Now we can actually destroy imageView
13481     vkDestroyImageView(m_device->device(), view, NULL);
13482     vkDestroySampler(m_device->device(), sampler, nullptr);
13483     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13484     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13485     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13486 }
13487
13488 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
13489     TEST_DESCRIPTION("Delete in-use bufferView.");
13490
13491     ASSERT_NO_FATAL_FAILURE(InitState());
13492     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13493
13494     VkDescriptorPoolSize ds_type_count;
13495     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13496     ds_type_count.descriptorCount = 1;
13497
13498     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13499     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13500     ds_pool_ci.maxSets = 1;
13501     ds_pool_ci.poolSizeCount = 1;
13502     ds_pool_ci.pPoolSizes = &ds_type_count;
13503
13504     VkDescriptorPool ds_pool;
13505     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13506     ASSERT_VK_SUCCESS(err);
13507
13508     VkDescriptorSetLayoutBinding layout_binding;
13509     layout_binding.binding = 0;
13510     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13511     layout_binding.descriptorCount = 1;
13512     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13513     layout_binding.pImmutableSamplers = NULL;
13514
13515     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13516     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13517     ds_layout_ci.bindingCount = 1;
13518     ds_layout_ci.pBindings = &layout_binding;
13519     VkDescriptorSetLayout ds_layout;
13520     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13521     ASSERT_VK_SUCCESS(err);
13522
13523     VkDescriptorSetAllocateInfo alloc_info = {};
13524     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13525     alloc_info.descriptorSetCount = 1;
13526     alloc_info.descriptorPool = ds_pool;
13527     alloc_info.pSetLayouts = &ds_layout;
13528     VkDescriptorSet descriptor_set;
13529     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13530     ASSERT_VK_SUCCESS(err);
13531
13532     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13533     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13534     pipeline_layout_ci.pNext = NULL;
13535     pipeline_layout_ci.setLayoutCount = 1;
13536     pipeline_layout_ci.pSetLayouts = &ds_layout;
13537
13538     VkPipelineLayout pipeline_layout;
13539     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13540     ASSERT_VK_SUCCESS(err);
13541
13542     VkBuffer buffer;
13543     uint32_t queue_family_index = 0;
13544     VkBufferCreateInfo buffer_create_info = {};
13545     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
13546     buffer_create_info.size = 1024;
13547     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
13548     buffer_create_info.queueFamilyIndexCount = 1;
13549     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
13550
13551     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
13552     ASSERT_VK_SUCCESS(err);
13553
13554     VkMemoryRequirements memory_reqs;
13555     VkDeviceMemory buffer_memory;
13556
13557     VkMemoryAllocateInfo memory_info = {};
13558     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
13559     memory_info.allocationSize = 0;
13560     memory_info.memoryTypeIndex = 0;
13561
13562     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
13563     memory_info.allocationSize = memory_reqs.size;
13564     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
13565     ASSERT_TRUE(pass);
13566
13567     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
13568     ASSERT_VK_SUCCESS(err);
13569     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
13570     ASSERT_VK_SUCCESS(err);
13571
13572     VkBufferView view;
13573     VkBufferViewCreateInfo bvci = {};
13574     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
13575     bvci.buffer = buffer;
13576     bvci.format = VK_FORMAT_R8_UNORM;
13577     bvci.range = VK_WHOLE_SIZE;
13578
13579     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
13580     ASSERT_VK_SUCCESS(err);
13581
13582     VkWriteDescriptorSet descriptor_write = {};
13583     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13584     descriptor_write.dstSet = descriptor_set;
13585     descriptor_write.dstBinding = 0;
13586     descriptor_write.descriptorCount = 1;
13587     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13588     descriptor_write.pTexelBufferView = &view;
13589
13590     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13591
13592     char const *vsSource = "#version 450\n"
13593                            "\n"
13594                            "out gl_PerVertex { \n"
13595                            "    vec4 gl_Position;\n"
13596                            "};\n"
13597                            "void main(){\n"
13598                            "   gl_Position = vec4(1);\n"
13599                            "}\n";
13600     char const *fsSource = "#version 450\n"
13601                            "\n"
13602                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
13603                            "layout(location=0) out vec4 x;\n"
13604                            "void main(){\n"
13605                            "   x = imageLoad(s, 0);\n"
13606                            "}\n";
13607     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13608     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13609     VkPipelineObj pipe(m_device);
13610     pipe.AddShader(&vs);
13611     pipe.AddShader(&fs);
13612     pipe.AddColorAttachment();
13613     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13614
13615     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
13616
13617     BeginCommandBuffer();
13618     VkViewport viewport = {0, 0, 16, 16, 0, 1};
13619     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
13620     VkRect2D scissor = {{0, 0}, {16, 16}};
13621     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
13622     // Bind pipeline to cmd buffer
13623     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13624     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13625                             &descriptor_set, 0, nullptr);
13626     Draw(1, 0, 0, 0);
13627     EndCommandBuffer();
13628
13629     VkSubmitInfo submit_info = {};
13630     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13631     submit_info.commandBufferCount = 1;
13632     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13633     // Submit cmd buffer and then destroy bufferView while in-flight
13634     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13635
13636     vkDestroyBufferView(m_device->device(), view, nullptr);
13637     m_errorMonitor->VerifyFound();
13638     vkQueueWaitIdle(m_device->m_queue);
13639     // Now we can actually destroy bufferView
13640     vkDestroyBufferView(m_device->device(), view, NULL);
13641     vkDestroyBuffer(m_device->device(), buffer, NULL);
13642     vkFreeMemory(m_device->device(), buffer_memory, NULL);
13643     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13644     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13645     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13646 }
13647
13648 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
13649     TEST_DESCRIPTION("Delete in-use sampler.");
13650
13651     ASSERT_NO_FATAL_FAILURE(InitState());
13652     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13653
13654     VkDescriptorPoolSize ds_type_count;
13655     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13656     ds_type_count.descriptorCount = 1;
13657
13658     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13659     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13660     ds_pool_ci.maxSets = 1;
13661     ds_pool_ci.poolSizeCount = 1;
13662     ds_pool_ci.pPoolSizes = &ds_type_count;
13663
13664     VkDescriptorPool ds_pool;
13665     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13666     ASSERT_VK_SUCCESS(err);
13667
13668     VkSamplerCreateInfo sampler_ci = {};
13669     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13670     sampler_ci.pNext = NULL;
13671     sampler_ci.magFilter = VK_FILTER_NEAREST;
13672     sampler_ci.minFilter = VK_FILTER_NEAREST;
13673     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13674     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13675     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13676     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13677     sampler_ci.mipLodBias = 1.0;
13678     sampler_ci.anisotropyEnable = VK_FALSE;
13679     sampler_ci.maxAnisotropy = 1;
13680     sampler_ci.compareEnable = VK_FALSE;
13681     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13682     sampler_ci.minLod = 1.0;
13683     sampler_ci.maxLod = 1.0;
13684     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13685     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13686     VkSampler sampler;
13687
13688     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13689     ASSERT_VK_SUCCESS(err);
13690
13691     VkDescriptorSetLayoutBinding layout_binding;
13692     layout_binding.binding = 0;
13693     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13694     layout_binding.descriptorCount = 1;
13695     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13696     layout_binding.pImmutableSamplers = NULL;
13697
13698     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13699     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13700     ds_layout_ci.bindingCount = 1;
13701     ds_layout_ci.pBindings = &layout_binding;
13702     VkDescriptorSetLayout ds_layout;
13703     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13704     ASSERT_VK_SUCCESS(err);
13705
13706     VkDescriptorSetAllocateInfo alloc_info = {};
13707     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13708     alloc_info.descriptorSetCount = 1;
13709     alloc_info.descriptorPool = ds_pool;
13710     alloc_info.pSetLayouts = &ds_layout;
13711     VkDescriptorSet descriptor_set;
13712     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13713     ASSERT_VK_SUCCESS(err);
13714
13715     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13716     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13717     pipeline_layout_ci.pNext = NULL;
13718     pipeline_layout_ci.setLayoutCount = 1;
13719     pipeline_layout_ci.pSetLayouts = &ds_layout;
13720
13721     VkPipelineLayout pipeline_layout;
13722     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13723     ASSERT_VK_SUCCESS(err);
13724
13725     VkImageObj image(m_device);
13726     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13727     ASSERT_TRUE(image.initialized());
13728
13729     VkImageView view;
13730     VkImageViewCreateInfo ivci = {};
13731     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13732     ivci.image = image.handle();
13733     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13734     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13735     ivci.subresourceRange.layerCount = 1;
13736     ivci.subresourceRange.baseMipLevel = 0;
13737     ivci.subresourceRange.levelCount = 1;
13738     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13739
13740     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13741     ASSERT_VK_SUCCESS(err);
13742
13743     VkDescriptorImageInfo image_info{};
13744     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13745     image_info.imageView = view;
13746     image_info.sampler = sampler;
13747
13748     VkWriteDescriptorSet descriptor_write = {};
13749     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13750     descriptor_write.dstSet = descriptor_set;
13751     descriptor_write.dstBinding = 0;
13752     descriptor_write.descriptorCount = 1;
13753     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13754     descriptor_write.pImageInfo = &image_info;
13755
13756     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13757
13758     // Create PSO to use the sampler
13759     char const *vsSource = "#version 450\n"
13760                            "\n"
13761                            "out gl_PerVertex { \n"
13762                            "    vec4 gl_Position;\n"
13763                            "};\n"
13764                            "void main(){\n"
13765                            "   gl_Position = vec4(1);\n"
13766                            "}\n";
13767     char const *fsSource = "#version 450\n"
13768                            "\n"
13769                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13770                            "layout(location=0) out vec4 x;\n"
13771                            "void main(){\n"
13772                            "   x = texture(s, vec2(1));\n"
13773                            "}\n";
13774     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13775     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13776     VkPipelineObj pipe(m_device);
13777     pipe.AddShader(&vs);
13778     pipe.AddShader(&fs);
13779     pipe.AddColorAttachment();
13780     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13781
13782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x");
13783
13784     BeginCommandBuffer();
13785     // Bind pipeline to cmd buffer
13786     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13787     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13788                             &descriptor_set, 0, nullptr);
13789     Draw(1, 0, 0, 0);
13790     EndCommandBuffer();
13791     // Submit cmd buffer then destroy sampler
13792     VkSubmitInfo submit_info = {};
13793     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13794     submit_info.commandBufferCount = 1;
13795     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13796     // Submit cmd buffer and then destroy sampler while in-flight
13797     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13798
13799     vkDestroySampler(m_device->device(), sampler, nullptr);
13800     m_errorMonitor->VerifyFound();
13801     vkQueueWaitIdle(m_device->m_queue);
13802     // Now we can actually destroy sampler
13803     vkDestroySampler(m_device->device(), sampler, nullptr);
13804     vkDestroyImageView(m_device->device(), view, NULL);
13805     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13806     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13807     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13808 }
13809
13810 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
13811     TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already "
13812                      "signaled but not waited on by the queue. Wait on a "
13813                      "fence that has not yet been submitted to a queue.");
13814
13815     ASSERT_NO_FATAL_FAILURE(InitState());
13816     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13817
13818     const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
13819     const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during "
13820                                              "acquire next image.";
13821
13822     BeginCommandBuffer();
13823     EndCommandBuffer();
13824
13825     VkSemaphoreCreateInfo semaphore_create_info = {};
13826     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13827     VkSemaphore semaphore;
13828     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13829     VkSubmitInfo submit_info = {};
13830     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13831     submit_info.commandBufferCount = 1;
13832     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13833     submit_info.signalSemaphoreCount = 1;
13834     submit_info.pSignalSemaphores = &semaphore;
13835     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13836     m_errorMonitor->SetDesiredFailureMsg(0, "");
13837     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13838     BeginCommandBuffer();
13839     EndCommandBuffer();
13840     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
13841     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13842     m_errorMonitor->VerifyFound();
13843
13844     VkFenceCreateInfo fence_create_info = {};
13845     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13846     VkFence fence;
13847     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13848
13849     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
13850     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
13851     m_errorMonitor->VerifyFound();
13852
13853     vkDeviceWaitIdle(m_device->device());
13854     vkDestroyFence(m_device->device(), fence, nullptr);
13855     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13856 }
13857
13858 TEST_F(VkLayerTest, FramebufferIncompatible) {
13859     TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
13860                      "that does not match the framebuffer for the active "
13861                      "renderpass.");
13862     ASSERT_NO_FATAL_FAILURE(InitState());
13863     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13864
13865     // A renderpass with one color attachment.
13866     VkAttachmentDescription attachment = {0,
13867                                           VK_FORMAT_B8G8R8A8_UNORM,
13868                                           VK_SAMPLE_COUNT_1_BIT,
13869                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13870                                           VK_ATTACHMENT_STORE_OP_STORE,
13871                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13872                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
13873                                           VK_IMAGE_LAYOUT_UNDEFINED,
13874                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13875
13876     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13877
13878     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
13879
13880     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
13881
13882     VkRenderPass rp;
13883     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
13884     ASSERT_VK_SUCCESS(err);
13885
13886     // A compatible framebuffer.
13887     VkImageObj image(m_device);
13888     image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13889     ASSERT_TRUE(image.initialized());
13890
13891     VkImageViewCreateInfo ivci = {
13892         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
13893         nullptr,
13894         0,
13895         image.handle(),
13896         VK_IMAGE_VIEW_TYPE_2D,
13897         VK_FORMAT_B8G8R8A8_UNORM,
13898         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13899          VK_COMPONENT_SWIZZLE_IDENTITY},
13900         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
13901     };
13902     VkImageView view;
13903     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
13904     ASSERT_VK_SUCCESS(err);
13905
13906     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
13907     VkFramebuffer fb;
13908     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
13909     ASSERT_VK_SUCCESS(err);
13910
13911     VkCommandBufferAllocateInfo cbai = {};
13912     cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13913     cbai.commandPool = m_commandPool;
13914     cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13915     cbai.commandBufferCount = 1;
13916
13917     VkCommandBuffer sec_cb;
13918     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
13919     ASSERT_VK_SUCCESS(err);
13920     VkCommandBufferBeginInfo cbbi = {};
13921     VkCommandBufferInheritanceInfo cbii = {};
13922     cbii.renderPass = renderPass();
13923     cbii.framebuffer = fb;
13924     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13925     cbbi.pNext = NULL;
13926     cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13927     cbbi.pInheritanceInfo = &cbii;
13928     vkBeginCommandBuffer(sec_cb, &cbbi);
13929     vkEndCommandBuffer(sec_cb);
13930
13931     VkCommandBufferBeginInfo cbbi2 = {
13932         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
13933         0, nullptr
13934     };
13935     vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
13936     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13937
13938     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13939                                          " that is not the same as the primaryCB's current active framebuffer ");
13940     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
13941     m_errorMonitor->VerifyFound();
13942     // Cleanup
13943     vkDestroyImageView(m_device->device(), view, NULL);
13944     vkDestroyRenderPass(m_device->device(), rp, NULL);
13945     vkDestroyFramebuffer(m_device->device(), fb, NULL);
13946 }
13947
13948 TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
13949     TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
13950                      "invalid value. If logicOp is not available, attempt to "
13951                      "use it and verify that we see the correct error.");
13952     ASSERT_NO_FATAL_FAILURE(InitState());
13953     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13954
13955     auto features = m_device->phy().features();
13956     // Set the expected error depending on whether or not logicOp available
13957     if (VK_FALSE == features.logicOp) {
13958         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not "
13959                                                                             "enabled, logicOpEnable must be "
13960                                                                             "VK_FALSE");
13961     } else {
13962         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
13963     }
13964     // Create a pipeline using logicOp
13965     VkResult err;
13966
13967     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13968     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13969
13970     VkPipelineLayout pipeline_layout;
13971     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13972     ASSERT_VK_SUCCESS(err);
13973
13974     VkPipelineViewportStateCreateInfo vp_state_ci = {};
13975     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13976     vp_state_ci.viewportCount = 1;
13977     VkViewport vp = {}; // Just need dummy vp to point to
13978     vp_state_ci.pViewports = &vp;
13979     vp_state_ci.scissorCount = 1;
13980     VkRect2D scissors = {}; // Dummy scissors to point to
13981     vp_state_ci.pScissors = &scissors;
13982
13983     VkPipelineShaderStageCreateInfo shaderStages[2];
13984     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
13985
13986     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13987     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13988     shaderStages[0] = vs.GetStageCreateInfo();
13989     shaderStages[1] = fs.GetStageCreateInfo();
13990
13991     VkPipelineVertexInputStateCreateInfo vi_ci = {};
13992     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13993
13994     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
13995     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13996     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13997
13998     VkPipelineRasterizationStateCreateInfo rs_ci = {};
13999     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14000     rs_ci.lineWidth = 1.0f;
14001
14002     VkPipelineColorBlendAttachmentState att = {};
14003     att.blendEnable = VK_FALSE;
14004     att.colorWriteMask = 0xf;
14005
14006     VkPipelineColorBlendStateCreateInfo cb_ci = {};
14007     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
14008     // Enable logicOp & set logicOp to value 1 beyond allowed entries
14009     cb_ci.logicOpEnable = VK_TRUE;
14010     cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
14011     cb_ci.attachmentCount = 1;
14012     cb_ci.pAttachments = &att;
14013
14014     VkPipelineMultisampleStateCreateInfo ms_ci = {};
14015     ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14016     ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14017
14018     VkGraphicsPipelineCreateInfo gp_ci = {};
14019     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14020     gp_ci.stageCount = 2;
14021     gp_ci.pStages = shaderStages;
14022     gp_ci.pVertexInputState = &vi_ci;
14023     gp_ci.pInputAssemblyState = &ia_ci;
14024     gp_ci.pViewportState = &vp_state_ci;
14025     gp_ci.pRasterizationState = &rs_ci;
14026     gp_ci.pColorBlendState = &cb_ci;
14027     gp_ci.pMultisampleState = &ms_ci;
14028     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14029     gp_ci.layout = pipeline_layout;
14030     gp_ci.renderPass = renderPass();
14031
14032     VkPipelineCacheCreateInfo pc_ci = {};
14033     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14034
14035     VkPipeline pipeline;
14036     VkPipelineCache pipelineCache;
14037     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
14038     ASSERT_VK_SUCCESS(err);
14039
14040     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
14041     m_errorMonitor->VerifyFound();
14042     if (VK_SUCCESS == err) {
14043         vkDestroyPipeline(m_device->device(), pipeline, NULL);
14044     }
14045     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
14046     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
14047 }
14048 #endif // DRAW_STATE_TESTS
14049
14050 #if THREADING_TESTS
14051 #if GTEST_IS_THREADSAFE
14052 struct thread_data_struct {
14053     VkCommandBuffer commandBuffer;
14054     VkEvent event;
14055     bool bailout;
14056 };
14057
14058 extern "C" void *AddToCommandBuffer(void *arg) {
14059     struct thread_data_struct *data = (struct thread_data_struct *)arg;
14060
14061     for (int i = 0; i < 80000; i++) {
14062         vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
14063         if (data->bailout) {
14064             break;
14065         }
14066     }
14067     return NULL;
14068 }
14069
14070 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
14071     test_platform_thread thread;
14072
14073     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
14074
14075     ASSERT_NO_FATAL_FAILURE(InitState());
14076     ASSERT_NO_FATAL_FAILURE(InitViewport());
14077     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14078
14079     // Calls AllocateCommandBuffers
14080     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
14081
14082     // Avoid creating RenderPass
14083     commandBuffer.BeginCommandBuffer();
14084
14085     VkEventCreateInfo event_info;
14086     VkEvent event;
14087     VkResult err;
14088
14089     memset(&event_info, 0, sizeof(event_info));
14090     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
14091
14092     err = vkCreateEvent(device(), &event_info, NULL, &event);
14093     ASSERT_VK_SUCCESS(err);
14094
14095     err = vkResetEvent(device(), event);
14096     ASSERT_VK_SUCCESS(err);
14097
14098     struct thread_data_struct data;
14099     data.commandBuffer = commandBuffer.GetBufferHandle();
14100     data.event = event;
14101     data.bailout = false;
14102     m_errorMonitor->SetBailout(&data.bailout);
14103
14104     // First do some correct operations using multiple threads.
14105     // Add many entries to command buffer from another thread.
14106     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14107     // Make non-conflicting calls from this thread at the same time.
14108     for (int i = 0; i < 80000; i++) {
14109         uint32_t count;
14110         vkEnumeratePhysicalDevices(instance(), &count, NULL);
14111     }
14112     test_platform_thread_join(thread, NULL);
14113
14114     // Then do some incorrect operations using multiple threads.
14115     // Add many entries to command buffer from another thread.
14116     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14117     // Add many entries to command buffer from this thread at the same time.
14118     AddToCommandBuffer(&data);
14119
14120     test_platform_thread_join(thread, NULL);
14121     commandBuffer.EndCommandBuffer();
14122
14123     m_errorMonitor->SetBailout(NULL);
14124
14125     m_errorMonitor->VerifyFound();
14126
14127     vkDestroyEvent(device(), event, NULL);
14128 }
14129 #endif // GTEST_IS_THREADSAFE
14130 #endif // THREADING_TESTS
14131
14132 #if SHADER_CHECKER_TESTS
14133 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
14134     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14135                      "with an impossible code size");
14136
14137     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
14138
14139     ASSERT_NO_FATAL_FAILURE(InitState());
14140     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14141
14142     VkShaderModule module;
14143     VkShaderModuleCreateInfo moduleCreateInfo;
14144     struct icd_spv_header spv;
14145
14146     spv.magic = ICD_SPV_MAGIC;
14147     spv.version = ICD_SPV_VERSION;
14148     spv.gen_magic = 0;
14149
14150     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14151     moduleCreateInfo.pNext = NULL;
14152     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14153     moduleCreateInfo.codeSize = 4;
14154     moduleCreateInfo.flags = 0;
14155     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14156
14157     m_errorMonitor->VerifyFound();
14158 }
14159
14160 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
14161     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14162                      "with a bad magic number");
14163
14164     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
14165
14166     ASSERT_NO_FATAL_FAILURE(InitState());
14167     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14168
14169     VkShaderModule module;
14170     VkShaderModuleCreateInfo moduleCreateInfo;
14171     struct icd_spv_header spv;
14172
14173     spv.magic = ~ICD_SPV_MAGIC;
14174     spv.version = ICD_SPV_VERSION;
14175     spv.gen_magic = 0;
14176
14177     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14178     moduleCreateInfo.pNext = NULL;
14179     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14180     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14181     moduleCreateInfo.flags = 0;
14182     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14183
14184     m_errorMonitor->VerifyFound();
14185 }
14186
14187 #if 0
14188 // Not currently covered by SPIRV-Tools validator
14189 TEST_F(VkLayerTest, InvalidSPIRVVersion) {
14190     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14191                                          "Invalid SPIR-V header");
14192
14193     ASSERT_NO_FATAL_FAILURE(InitState());
14194     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14195
14196     VkShaderModule module;
14197     VkShaderModuleCreateInfo moduleCreateInfo;
14198     struct icd_spv_header spv;
14199
14200     spv.magic = ICD_SPV_MAGIC;
14201     spv.version = ~ICD_SPV_VERSION;
14202     spv.gen_magic = 0;
14203
14204     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14205     moduleCreateInfo.pNext = NULL;
14206
14207     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14208     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14209     moduleCreateInfo.flags = 0;
14210     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14211
14212     m_errorMonitor->VerifyFound();
14213 }
14214 #endif
14215
14216 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
14217     TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
14218                      "is not consumed by the fragment stage");
14219     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
14220
14221     ASSERT_NO_FATAL_FAILURE(InitState());
14222     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14223
14224     char const *vsSource = "#version 450\n"
14225                            "\n"
14226                            "layout(location=0) out float x;\n"
14227                            "out gl_PerVertex {\n"
14228                            "    vec4 gl_Position;\n"
14229                            "};\n"
14230                            "void main(){\n"
14231                            "   gl_Position = vec4(1);\n"
14232                            "   x = 0;\n"
14233                            "}\n";
14234     char const *fsSource = "#version 450\n"
14235                            "\n"
14236                            "layout(location=0) out vec4 color;\n"
14237                            "void main(){\n"
14238                            "   color = vec4(1);\n"
14239                            "}\n";
14240
14241     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14242     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14243
14244     VkPipelineObj pipe(m_device);
14245     pipe.AddColorAttachment();
14246     pipe.AddShader(&vs);
14247     pipe.AddShader(&fs);
14248
14249     VkDescriptorSetObj descriptorSet(m_device);
14250     descriptorSet.AppendDummy();
14251     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14252
14253     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14254
14255     m_errorMonitor->VerifyFound();
14256 }
14257
14258 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
14259     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14260                      "which is not present in the outputs of the previous stage");
14261
14262     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14263
14264     ASSERT_NO_FATAL_FAILURE(InitState());
14265     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14266
14267     char const *vsSource = "#version 450\n"
14268                            "\n"
14269                            "out gl_PerVertex {\n"
14270                            "    vec4 gl_Position;\n"
14271                            "};\n"
14272                            "void main(){\n"
14273                            "   gl_Position = vec4(1);\n"
14274                            "}\n";
14275     char const *fsSource = "#version 450\n"
14276                            "\n"
14277                            "layout(location=0) in float x;\n"
14278                            "layout(location=0) out vec4 color;\n"
14279                            "void main(){\n"
14280                            "   color = vec4(x);\n"
14281                            "}\n";
14282
14283     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14284     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14285
14286     VkPipelineObj pipe(m_device);
14287     pipe.AddColorAttachment();
14288     pipe.AddShader(&vs);
14289     pipe.AddShader(&fs);
14290
14291     VkDescriptorSetObj descriptorSet(m_device);
14292     descriptorSet.AppendDummy();
14293     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14294
14295     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14296
14297     m_errorMonitor->VerifyFound();
14298 }
14299
14300 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
14301     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14302                      "within an interace block, which is not present in the outputs "
14303                      "of the previous stage.");
14304     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14305
14306     ASSERT_NO_FATAL_FAILURE(InitState());
14307     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14308
14309     char const *vsSource = "#version 450\n"
14310                            "\n"
14311                            "out gl_PerVertex {\n"
14312                            "    vec4 gl_Position;\n"
14313                            "};\n"
14314                            "void main(){\n"
14315                            "   gl_Position = vec4(1);\n"
14316                            "}\n";
14317     char const *fsSource = "#version 450\n"
14318                            "\n"
14319                            "in block { layout(location=0) float x; } ins;\n"
14320                            "layout(location=0) out vec4 color;\n"
14321                            "void main(){\n"
14322                            "   color = vec4(ins.x);\n"
14323                            "}\n";
14324
14325     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14326     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14327
14328     VkPipelineObj pipe(m_device);
14329     pipe.AddColorAttachment();
14330     pipe.AddShader(&vs);
14331     pipe.AddShader(&fs);
14332
14333     VkDescriptorSetObj descriptorSet(m_device);
14334     descriptorSet.AppendDummy();
14335     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14336
14337     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14338
14339     m_errorMonitor->VerifyFound();
14340 }
14341
14342 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
14343     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
14344                      "across the VS->FS interface");
14345     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
14346                                                                         "output arr[2] of float32' vs 'ptr to "
14347                                                                         "input arr[3] of float32'");
14348
14349     ASSERT_NO_FATAL_FAILURE(InitState());
14350     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14351
14352     char const *vsSource = "#version 450\n"
14353                            "\n"
14354                            "layout(location=0) out float x[2];\n"
14355                            "out gl_PerVertex {\n"
14356                            "    vec4 gl_Position;\n"
14357                            "};\n"
14358                            "void main(){\n"
14359                            "   x[0] = 0; x[1] = 0;\n"
14360                            "   gl_Position = vec4(1);\n"
14361                            "}\n";
14362     char const *fsSource = "#version 450\n"
14363                            "\n"
14364                            "layout(location=0) in float x[3];\n"
14365                            "layout(location=0) out vec4 color;\n"
14366                            "void main(){\n"
14367                            "   color = vec4(x[0] + x[1] + x[2]);\n"
14368                            "}\n";
14369
14370     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14371     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14372
14373     VkPipelineObj pipe(m_device);
14374     pipe.AddColorAttachment();
14375     pipe.AddShader(&vs);
14376     pipe.AddShader(&fs);
14377
14378     VkDescriptorSetObj descriptorSet(m_device);
14379     descriptorSet.AppendDummy();
14380     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14381
14382     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14383
14384     m_errorMonitor->VerifyFound();
14385 }
14386
14387 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
14388     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14389                      "the VS->FS interface");
14390     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14391
14392     ASSERT_NO_FATAL_FAILURE(InitState());
14393     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14394
14395     char const *vsSource = "#version 450\n"
14396                            "\n"
14397                            "layout(location=0) out int x;\n"
14398                            "out gl_PerVertex {\n"
14399                            "    vec4 gl_Position;\n"
14400                            "};\n"
14401                            "void main(){\n"
14402                            "   x = 0;\n"
14403                            "   gl_Position = vec4(1);\n"
14404                            "}\n";
14405     char const *fsSource = "#version 450\n"
14406                            "\n"
14407                            "layout(location=0) in float x;\n" /* VS writes int */
14408                            "layout(location=0) out vec4 color;\n"
14409                            "void main(){\n"
14410                            "   color = vec4(x);\n"
14411                            "}\n";
14412
14413     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14414     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14415
14416     VkPipelineObj pipe(m_device);
14417     pipe.AddColorAttachment();
14418     pipe.AddShader(&vs);
14419     pipe.AddShader(&fs);
14420
14421     VkDescriptorSetObj descriptorSet(m_device);
14422     descriptorSet.AppendDummy();
14423     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14424
14425     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14426
14427     m_errorMonitor->VerifyFound();
14428 }
14429
14430 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
14431     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14432                      "the VS->FS interface, when the variable is contained within "
14433                      "an interface block");
14434     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14435
14436     ASSERT_NO_FATAL_FAILURE(InitState());
14437     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14438
14439     char const *vsSource = "#version 450\n"
14440                            "\n"
14441                            "out block { layout(location=0) int x; } outs;\n"
14442                            "out gl_PerVertex {\n"
14443                            "    vec4 gl_Position;\n"
14444                            "};\n"
14445                            "void main(){\n"
14446                            "   outs.x = 0;\n"
14447                            "   gl_Position = vec4(1);\n"
14448                            "}\n";
14449     char const *fsSource = "#version 450\n"
14450                            "\n"
14451                            "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
14452                            "layout(location=0) out vec4 color;\n"
14453                            "void main(){\n"
14454                            "   color = vec4(ins.x);\n"
14455                            "}\n";
14456
14457     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14458     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14459
14460     VkPipelineObj pipe(m_device);
14461     pipe.AddColorAttachment();
14462     pipe.AddShader(&vs);
14463     pipe.AddShader(&fs);
14464
14465     VkDescriptorSetObj descriptorSet(m_device);
14466     descriptorSet.AppendDummy();
14467     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14468
14469     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14470
14471     m_errorMonitor->VerifyFound();
14472 }
14473
14474 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
14475     TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
14476                      "the VS->FS interface; This should manifest as a not-written/not-consumed "
14477                      "pair, but flushes out broken walking of the interfaces");
14478     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
14479
14480     ASSERT_NO_FATAL_FAILURE(InitState());
14481     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14482
14483     char const *vsSource = "#version 450\n"
14484                            "\n"
14485                            "out block { layout(location=1) float x; } outs;\n"
14486                            "out gl_PerVertex {\n"
14487                            "    vec4 gl_Position;\n"
14488                            "};\n"
14489                            "void main(){\n"
14490                            "   outs.x = 0;\n"
14491                            "   gl_Position = vec4(1);\n"
14492                            "}\n";
14493     char const *fsSource = "#version 450\n"
14494                            "\n"
14495                            "in block { layout(location=0) float x; } ins;\n"
14496                            "layout(location=0) out vec4 color;\n"
14497                            "void main(){\n"
14498                            "   color = vec4(ins.x);\n"
14499                            "}\n";
14500
14501     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14502     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14503
14504     VkPipelineObj pipe(m_device);
14505     pipe.AddColorAttachment();
14506     pipe.AddShader(&vs);
14507     pipe.AddShader(&fs);
14508
14509     VkDescriptorSetObj descriptorSet(m_device);
14510     descriptorSet.AppendDummy();
14511     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14512
14513     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14514
14515     m_errorMonitor->VerifyFound();
14516 }
14517
14518 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
14519     TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
14520                      "VS->FS interface. It's not enough to have the same set of locations in "
14521                      "use; matching is defined in terms of spirv variables.");
14522     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
14523
14524     ASSERT_NO_FATAL_FAILURE(InitState());
14525     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14526
14527     char const *vsSource = "#version 450\n"
14528                            "\n"
14529                            "out block { layout(location=0, component=0) float x; } outs;\n"
14530                            "out gl_PerVertex {\n"
14531                            "    vec4 gl_Position;\n"
14532                            "};\n"
14533                            "void main(){\n"
14534                            "   outs.x = 0;\n"
14535                            "   gl_Position = vec4(1);\n"
14536                            "}\n";
14537     char const *fsSource = "#version 450\n"
14538                            "\n"
14539                            "in block { layout(location=0, component=1) float x; } ins;\n"
14540                            "layout(location=0) out vec4 color;\n"
14541                            "void main(){\n"
14542                            "   color = vec4(ins.x);\n"
14543                            "}\n";
14544
14545     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14546     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14547
14548     VkPipelineObj pipe(m_device);
14549     pipe.AddColorAttachment();
14550     pipe.AddShader(&vs);
14551     pipe.AddShader(&fs);
14552
14553     VkDescriptorSetObj descriptorSet(m_device);
14554     descriptorSet.AppendDummy();
14555     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14556
14557     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14558
14559     m_errorMonitor->VerifyFound();
14560 }
14561
14562 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
14563     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
14564                      "not consumed by the vertex shader");
14565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14566
14567     ASSERT_NO_FATAL_FAILURE(InitState());
14568     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14569
14570     VkVertexInputBindingDescription input_binding;
14571     memset(&input_binding, 0, sizeof(input_binding));
14572
14573     VkVertexInputAttributeDescription input_attrib;
14574     memset(&input_attrib, 0, sizeof(input_attrib));
14575     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14576
14577     char const *vsSource = "#version 450\n"
14578                            "\n"
14579                            "out gl_PerVertex {\n"
14580                            "    vec4 gl_Position;\n"
14581                            "};\n"
14582                            "void main(){\n"
14583                            "   gl_Position = vec4(1);\n"
14584                            "}\n";
14585     char const *fsSource = "#version 450\n"
14586                            "\n"
14587                            "layout(location=0) out vec4 color;\n"
14588                            "void main(){\n"
14589                            "   color = vec4(1);\n"
14590                            "}\n";
14591
14592     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14593     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14594
14595     VkPipelineObj pipe(m_device);
14596     pipe.AddColorAttachment();
14597     pipe.AddShader(&vs);
14598     pipe.AddShader(&fs);
14599
14600     pipe.AddVertexInputBindings(&input_binding, 1);
14601     pipe.AddVertexInputAttribs(&input_attrib, 1);
14602
14603     VkDescriptorSetObj descriptorSet(m_device);
14604     descriptorSet.AppendDummy();
14605     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14606
14607     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14608
14609     m_errorMonitor->VerifyFound();
14610 }
14611
14612 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
14613     TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
14614                      "vertex attributes. This flushes out bad behavior in the interface walker");
14615     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14616
14617     ASSERT_NO_FATAL_FAILURE(InitState());
14618     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14619
14620     VkVertexInputBindingDescription input_binding;
14621     memset(&input_binding, 0, sizeof(input_binding));
14622
14623     VkVertexInputAttributeDescription input_attrib;
14624     memset(&input_attrib, 0, sizeof(input_attrib));
14625     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14626
14627     char const *vsSource = "#version 450\n"
14628                            "\n"
14629                            "layout(location=1) in float x;\n"
14630                            "out gl_PerVertex {\n"
14631                            "    vec4 gl_Position;\n"
14632                            "};\n"
14633                            "void main(){\n"
14634                            "   gl_Position = vec4(x);\n"
14635                            "}\n";
14636     char const *fsSource = "#version 450\n"
14637                            "\n"
14638                            "layout(location=0) out vec4 color;\n"
14639                            "void main(){\n"
14640                            "   color = vec4(1);\n"
14641                            "}\n";
14642
14643     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14644     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14645
14646     VkPipelineObj pipe(m_device);
14647     pipe.AddColorAttachment();
14648     pipe.AddShader(&vs);
14649     pipe.AddShader(&fs);
14650
14651     pipe.AddVertexInputBindings(&input_binding, 1);
14652     pipe.AddVertexInputAttribs(&input_attrib, 1);
14653
14654     VkDescriptorSetObj descriptorSet(m_device);
14655     descriptorSet.AppendDummy();
14656     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14657
14658     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14659
14660     m_errorMonitor->VerifyFound();
14661 }
14662
14663 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
14664     TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
14665                      "provided by a vertex attribute");
14666     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
14667
14668     ASSERT_NO_FATAL_FAILURE(InitState());
14669     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14670
14671     char const *vsSource = "#version 450\n"
14672                            "\n"
14673                            "layout(location=0) in vec4 x;\n" /* not provided */
14674                            "out gl_PerVertex {\n"
14675                            "    vec4 gl_Position;\n"
14676                            "};\n"
14677                            "void main(){\n"
14678                            "   gl_Position = x;\n"
14679                            "}\n";
14680     char const *fsSource = "#version 450\n"
14681                            "\n"
14682                            "layout(location=0) out vec4 color;\n"
14683                            "void main(){\n"
14684                            "   color = vec4(1);\n"
14685                            "}\n";
14686
14687     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14688     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14689
14690     VkPipelineObj pipe(m_device);
14691     pipe.AddColorAttachment();
14692     pipe.AddShader(&vs);
14693     pipe.AddShader(&fs);
14694
14695     VkDescriptorSetObj descriptorSet(m_device);
14696     descriptorSet.AppendDummy();
14697     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14698
14699     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14700
14701     m_errorMonitor->VerifyFound();
14702 }
14703
14704 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
14705     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
14706                      "fundamental type (float/int/uint) of an attribute and the "
14707                      "vertex shader input that consumes it");
14708     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
14709
14710     ASSERT_NO_FATAL_FAILURE(InitState());
14711     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14712
14713     VkVertexInputBindingDescription input_binding;
14714     memset(&input_binding, 0, sizeof(input_binding));
14715
14716     VkVertexInputAttributeDescription input_attrib;
14717     memset(&input_attrib, 0, sizeof(input_attrib));
14718     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14719
14720     char const *vsSource = "#version 450\n"
14721                            "\n"
14722                            "layout(location=0) in int x;\n" /* attrib provided float */
14723                            "out gl_PerVertex {\n"
14724                            "    vec4 gl_Position;\n"
14725                            "};\n"
14726                            "void main(){\n"
14727                            "   gl_Position = vec4(x);\n"
14728                            "}\n";
14729     char const *fsSource = "#version 450\n"
14730                            "\n"
14731                            "layout(location=0) out vec4 color;\n"
14732                            "void main(){\n"
14733                            "   color = vec4(1);\n"
14734                            "}\n";
14735
14736     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14737     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14738
14739     VkPipelineObj pipe(m_device);
14740     pipe.AddColorAttachment();
14741     pipe.AddShader(&vs);
14742     pipe.AddShader(&fs);
14743
14744     pipe.AddVertexInputBindings(&input_binding, 1);
14745     pipe.AddVertexInputAttribs(&input_attrib, 1);
14746
14747     VkDescriptorSetObj descriptorSet(m_device);
14748     descriptorSet.AppendDummy();
14749     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14750
14751     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14752
14753     m_errorMonitor->VerifyFound();
14754 }
14755
14756 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
14757     TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
14758                      "shaders for the same stage");
14759     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14760                                          "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
14761
14762     ASSERT_NO_FATAL_FAILURE(InitState());
14763     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14764
14765     char const *vsSource = "#version 450\n"
14766                            "\n"
14767                            "out gl_PerVertex {\n"
14768                            "    vec4 gl_Position;\n"
14769                            "};\n"
14770                            "void main(){\n"
14771                            "   gl_Position = vec4(1);\n"
14772                            "}\n";
14773     char const *fsSource = "#version 450\n"
14774                            "\n"
14775                            "layout(location=0) out vec4 color;\n"
14776                            "void main(){\n"
14777                            "   color = vec4(1);\n"
14778                            "}\n";
14779
14780     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14781     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14782
14783     VkPipelineObj pipe(m_device);
14784     pipe.AddColorAttachment();
14785     pipe.AddShader(&vs);
14786     pipe.AddShader(&vs);
14787     pipe.AddShader(&fs);
14788
14789     VkDescriptorSetObj descriptorSet(m_device);
14790     descriptorSet.AppendDummy();
14791     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14792
14793     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14794
14795     m_errorMonitor->VerifyFound();
14796 }
14797
14798 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
14799     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
14800                      "as vertex attributes");
14801     m_errorMonitor->ExpectSuccess();
14802
14803     ASSERT_NO_FATAL_FAILURE(InitState());
14804     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14805
14806     VkVertexInputBindingDescription input_binding;
14807     memset(&input_binding, 0, sizeof(input_binding));
14808
14809     VkVertexInputAttributeDescription input_attribs[2];
14810     memset(input_attribs, 0, sizeof(input_attribs));
14811
14812     for (int i = 0; i < 2; i++) {
14813         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14814         input_attribs[i].location = i;
14815     }
14816
14817     char const *vsSource = "#version 450\n"
14818                            "\n"
14819                            "layout(location=0) in mat2x4 x;\n"
14820                            "out gl_PerVertex {\n"
14821                            "    vec4 gl_Position;\n"
14822                            "};\n"
14823                            "void main(){\n"
14824                            "   gl_Position = x[0] + x[1];\n"
14825                            "}\n";
14826     char const *fsSource = "#version 450\n"
14827                            "\n"
14828                            "layout(location=0) out vec4 color;\n"
14829                            "void main(){\n"
14830                            "   color = vec4(1);\n"
14831                            "}\n";
14832
14833     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14834     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14835
14836     VkPipelineObj pipe(m_device);
14837     pipe.AddColorAttachment();
14838     pipe.AddShader(&vs);
14839     pipe.AddShader(&fs);
14840
14841     pipe.AddVertexInputBindings(&input_binding, 1);
14842     pipe.AddVertexInputAttribs(input_attribs, 2);
14843
14844     VkDescriptorSetObj descriptorSet(m_device);
14845     descriptorSet.AppendDummy();
14846     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14847
14848     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14849
14850     /* expect success */
14851     m_errorMonitor->VerifyNotFound();
14852 }
14853
14854 TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
14855     m_errorMonitor->ExpectSuccess();
14856
14857     ASSERT_NO_FATAL_FAILURE(InitState());
14858     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14859
14860     VkVertexInputBindingDescription input_binding;
14861     memset(&input_binding, 0, sizeof(input_binding));
14862
14863     VkVertexInputAttributeDescription input_attribs[2];
14864     memset(input_attribs, 0, sizeof(input_attribs));
14865
14866     for (int i = 0; i < 2; i++) {
14867         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14868         input_attribs[i].location = i;
14869     }
14870
14871     char const *vsSource = "#version 450\n"
14872                            "\n"
14873                            "layout(location=0) in vec4 x[2];\n"
14874                            "out gl_PerVertex {\n"
14875                            "    vec4 gl_Position;\n"
14876                            "};\n"
14877                            "void main(){\n"
14878                            "   gl_Position = x[0] + x[1];\n"
14879                            "}\n";
14880     char const *fsSource = "#version 450\n"
14881                            "\n"
14882                            "layout(location=0) out vec4 color;\n"
14883                            "void main(){\n"
14884                            "   color = vec4(1);\n"
14885                            "}\n";
14886
14887     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14888     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14889
14890     VkPipelineObj pipe(m_device);
14891     pipe.AddColorAttachment();
14892     pipe.AddShader(&vs);
14893     pipe.AddShader(&fs);
14894
14895     pipe.AddVertexInputBindings(&input_binding, 1);
14896     pipe.AddVertexInputAttribs(input_attribs, 2);
14897
14898     VkDescriptorSetObj descriptorSet(m_device);
14899     descriptorSet.AppendDummy();
14900     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14901
14902     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14903
14904     m_errorMonitor->VerifyNotFound();
14905 }
14906
14907 TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
14908     TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
14909                      "through multiple vertex shader inputs, each consuming a different "
14910                      "subset of the components.");
14911     m_errorMonitor->ExpectSuccess();
14912
14913     ASSERT_NO_FATAL_FAILURE(InitState());
14914     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14915
14916     VkVertexInputBindingDescription input_binding;
14917     memset(&input_binding, 0, sizeof(input_binding));
14918
14919     VkVertexInputAttributeDescription input_attribs[3];
14920     memset(input_attribs, 0, sizeof(input_attribs));
14921
14922     for (int i = 0; i < 3; i++) {
14923         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14924         input_attribs[i].location = i;
14925     }
14926
14927     char const *vsSource = "#version 450\n"
14928                            "\n"
14929                            "layout(location=0) in vec4 x;\n"
14930                            "layout(location=1) in vec3 y1;\n"
14931                            "layout(location=1, component=3) in float y2;\n"
14932                            "layout(location=2) in vec4 z;\n"
14933                            "out gl_PerVertex {\n"
14934                            "    vec4 gl_Position;\n"
14935                            "};\n"
14936                            "void main(){\n"
14937                            "   gl_Position = x + vec4(y1, y2) + z;\n"
14938                            "}\n";
14939     char const *fsSource = "#version 450\n"
14940                            "\n"
14941                            "layout(location=0) out vec4 color;\n"
14942                            "void main(){\n"
14943                            "   color = vec4(1);\n"
14944                            "}\n";
14945
14946     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14947     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14948
14949     VkPipelineObj pipe(m_device);
14950     pipe.AddColorAttachment();
14951     pipe.AddShader(&vs);
14952     pipe.AddShader(&fs);
14953
14954     pipe.AddVertexInputBindings(&input_binding, 1);
14955     pipe.AddVertexInputAttribs(input_attribs, 3);
14956
14957     VkDescriptorSetObj descriptorSet(m_device);
14958     descriptorSet.AppendDummy();
14959     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14960
14961     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14962
14963     m_errorMonitor->VerifyNotFound();
14964 }
14965
14966 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
14967     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14968                                          "No entrypoint found named `foo`");
14969
14970     ASSERT_NO_FATAL_FAILURE(InitState());
14971     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14972
14973     char const *vsSource = "#version 450\n"
14974                            "out gl_PerVertex {\n"
14975                            "    vec4 gl_Position;\n"
14976                            "};\n"
14977                            "void main(){\n"
14978                            "   gl_Position = vec4(0);\n"
14979                            "}\n";
14980     char const *fsSource = "#version 450\n"
14981                            "\n"
14982                            "layout(location=0) out vec4 color;\n"
14983                            "void main(){\n"
14984                            "   color = vec4(1);\n"
14985                            "}\n";
14986
14987     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14988     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
14989
14990     VkPipelineObj pipe(m_device);
14991     pipe.AddColorAttachment();
14992     pipe.AddShader(&vs);
14993     pipe.AddShader(&fs);
14994
14995     VkDescriptorSetObj descriptorSet(m_device);
14996     descriptorSet.AppendDummy();
14997     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14998
14999     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15000
15001     m_errorMonitor->VerifyFound();
15002 }
15003
15004 TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
15005     m_errorMonitor->ExpectSuccess();
15006
15007     ASSERT_NO_FATAL_FAILURE(InitState());
15008     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15009
15010     char const *vsSource = "#version 450\n"
15011                            "out gl_PerVertex {\n"
15012                            "    vec4 gl_Position;\n"
15013                            "};\n"
15014                            "void main(){\n"
15015                            "   gl_Position = vec4(0);\n"
15016                            "}\n";
15017     char const *fsSource = "#version 450\n"
15018                            "\n"
15019                            "layout(location=0) out vec4 color;\n"
15020                            "void main(){\n"
15021                            "   color = vec4(1);\n"
15022                            "}\n";
15023
15024     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15025     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15026
15027     VkPipelineObj pipe(m_device);
15028     pipe.AddColorAttachment();
15029     pipe.AddShader(&vs);
15030     pipe.AddShader(&fs);
15031
15032     VkDescriptorSetObj descriptorSet(m_device);
15033     descriptorSet.AppendDummy();
15034     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15035
15036     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15037
15038     m_errorMonitor->VerifyNotFound();
15039 }
15040
15041 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
15042     m_errorMonitor->SetDesiredFailureMsg(
15043         VK_DEBUG_REPORT_ERROR_BIT_EXT,
15044         "pDepthStencilState is NULL when rasterization is enabled and subpass "
15045         "uses a depth/stencil attachment");
15046
15047     ASSERT_NO_FATAL_FAILURE(InitState());
15048     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15049
15050     char const *vsSource = "#version 450\n"
15051                            "void main(){ gl_Position = vec4(0); }\n";
15052     char const *fsSource = "#version 450\n"
15053                            "\n"
15054                            "layout(location=0) out vec4 color;\n"
15055                            "void main(){\n"
15056                            "   color = vec4(1);\n"
15057                            "}\n";
15058
15059     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15060     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15061
15062     VkPipelineObj pipe(m_device);
15063     pipe.AddColorAttachment();
15064     pipe.AddShader(&vs);
15065     pipe.AddShader(&fs);
15066
15067     VkDescriptorSetObj descriptorSet(m_device);
15068     descriptorSet.AppendDummy();
15069     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15070
15071     VkAttachmentDescription attachments[] = {
15072         { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
15073           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15074           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15075           VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15076         },
15077         { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT,
15078           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15079           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15080           VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
15081         },
15082     };
15083     VkAttachmentReference refs[] = {
15084         { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
15085         { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL },
15086     };
15087     VkSubpassDescription subpass = {
15088         0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
15089         1, &refs[0], nullptr, &refs[1],
15090         0, nullptr
15091     };
15092     VkRenderPassCreateInfo rpci = {
15093         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
15094         0, 2, attachments, 1, &subpass, 0, nullptr
15095     };
15096     VkRenderPass rp;
15097     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15098     ASSERT_VK_SUCCESS(err);
15099
15100     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
15101
15102     m_errorMonitor->VerifyFound();
15103
15104     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15105 }
15106
15107 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
15108     TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
15109                      "set out in 14.1.3: fundamental type must match, and producer side must "
15110                      "have at least as many components");
15111     m_errorMonitor->ExpectSuccess();
15112
15113     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
15114
15115     ASSERT_NO_FATAL_FAILURE(InitState());
15116     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15117
15118     char const *vsSource = "#version 450\n"
15119                            "out gl_PerVertex {\n"
15120                            "    vec4 gl_Position;\n"
15121                            "};\n"
15122                            "layout(location=0) out vec3 x;\n"
15123                            "layout(location=1) out ivec3 y;\n"
15124                            "layout(location=2) out vec3 z;\n"
15125                            "void main(){\n"
15126                            "   gl_Position = vec4(0);\n"
15127                            "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
15128                            "}\n";
15129     char const *fsSource = "#version 450\n"
15130                            "\n"
15131                            "layout(location=0) out vec4 color;\n"
15132                            "layout(location=0) in float x;\n"
15133                            "layout(location=1) flat in int y;\n"
15134                            "layout(location=2) in vec2 z;\n"
15135                            "void main(){\n"
15136                            "   color = vec4(1 + x + y + z.x);\n"
15137                            "}\n";
15138
15139     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15140     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15141
15142     VkPipelineObj pipe(m_device);
15143     pipe.AddColorAttachment();
15144     pipe.AddShader(&vs);
15145     pipe.AddShader(&fs);
15146
15147     VkDescriptorSetObj descriptorSet(m_device);
15148     descriptorSet.AppendDummy();
15149     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15150
15151     VkResult err = VK_SUCCESS;
15152     err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15153     ASSERT_VK_SUCCESS(err);
15154
15155     m_errorMonitor->VerifyNotFound();
15156 }
15157
15158 TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
15159     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
15160                      "passed between the TCS and TES stages");
15161     m_errorMonitor->ExpectSuccess();
15162
15163     ASSERT_NO_FATAL_FAILURE(InitState());
15164     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15165
15166     if (!m_device->phy().features().tessellationShader) {
15167         printf("Device does not support tessellation shaders; skipped.\n");
15168         return;
15169     }
15170
15171     char const *vsSource = "#version 450\n"
15172                            "void main(){}\n";
15173     char const *tcsSource = "#version 450\n"
15174                             "layout(location=0) out int x[];\n"
15175                             "layout(vertices=3) out;\n"
15176                             "void main(){\n"
15177                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15178                             "   gl_TessLevelInner[0] = 1;\n"
15179                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15180                             "}\n";
15181     char const *tesSource = "#version 450\n"
15182                             "layout(triangles, equal_spacing, cw) in;\n"
15183                             "layout(location=0) in int x[];\n"
15184                             "out gl_PerVertex { vec4 gl_Position; };\n"
15185                             "void main(){\n"
15186                             "   gl_Position.xyz = gl_TessCoord;\n"
15187                             "   gl_Position.w = x[0] + x[1] + x[2];\n"
15188                             "}\n";
15189     char const *fsSource = "#version 450\n"
15190                            "layout(location=0) out vec4 color;\n"
15191                            "void main(){\n"
15192                            "   color = vec4(1);\n"
15193                            "}\n";
15194
15195     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15196     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15197     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15198     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15199
15200     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15201                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15202
15203     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15204
15205     VkPipelineObj pipe(m_device);
15206     pipe.SetInputAssembly(&iasci);
15207     pipe.SetTessellation(&tsci);
15208     pipe.AddColorAttachment();
15209     pipe.AddShader(&vs);
15210     pipe.AddShader(&tcs);
15211     pipe.AddShader(&tes);
15212     pipe.AddShader(&fs);
15213
15214     VkDescriptorSetObj descriptorSet(m_device);
15215     descriptorSet.AppendDummy();
15216     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15217
15218     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15219
15220     m_errorMonitor->VerifyNotFound();
15221 }
15222
15223 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
15224     TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
15225                      "interface block passed into the geometry shader. This "
15226                      "is interesting because the 'extra' array level is not "
15227                      "present on the member type, but on the block instance.");
15228     m_errorMonitor->ExpectSuccess();
15229
15230     ASSERT_NO_FATAL_FAILURE(InitState());
15231     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15232
15233     if (!m_device->phy().features().geometryShader) {
15234         printf("Device does not support geometry shaders; skipped.\n");
15235         return;
15236     }
15237
15238     char const *vsSource = "#version 450\n"
15239                            "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
15240                            "void main(){\n"
15241                            "   vs_out.x = vec4(1);\n"
15242                            "}\n";
15243     char const *gsSource = "#version 450\n"
15244                            "layout(triangles) in;\n"
15245                            "layout(triangle_strip, max_vertices=3) out;\n"
15246                            "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
15247                            "out gl_PerVertex { vec4 gl_Position; };\n"
15248                            "void main() {\n"
15249                            "   gl_Position = gs_in[0].x;\n"
15250                            "   EmitVertex();\n"
15251                            "}\n";
15252     char const *fsSource = "#version 450\n"
15253                            "layout(location=0) out vec4 color;\n"
15254                            "void main(){\n"
15255                            "   color = vec4(1);\n"
15256                            "}\n";
15257
15258     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15259     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
15260     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15261
15262     VkPipelineObj pipe(m_device);
15263     pipe.AddColorAttachment();
15264     pipe.AddShader(&vs);
15265     pipe.AddShader(&gs);
15266     pipe.AddShader(&fs);
15267
15268     VkDescriptorSetObj descriptorSet(m_device);
15269     descriptorSet.AppendDummy();
15270     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15271
15272     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15273
15274     m_errorMonitor->VerifyNotFound();
15275 }
15276
15277 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
15278     TEST_DESCRIPTION("Test that an error is produced for a variable output from "
15279                      "the TCS without the patch decoration, but consumed in the TES "
15280                      "with the decoration.");
15281     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage "
15282                                                                         "but per-patch in tessellation evaluation shader stage");
15283
15284     ASSERT_NO_FATAL_FAILURE(InitState());
15285     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15286
15287     if (!m_device->phy().features().tessellationShader) {
15288         printf("Device does not support tessellation shaders; skipped.\n");
15289         return;
15290     }
15291
15292     char const *vsSource = "#version 450\n"
15293                            "void main(){}\n";
15294     char const *tcsSource = "#version 450\n"
15295                             "layout(location=0) out int x[];\n"
15296                             "layout(vertices=3) out;\n"
15297                             "void main(){\n"
15298                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15299                             "   gl_TessLevelInner[0] = 1;\n"
15300                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15301                             "}\n";
15302     char const *tesSource = "#version 450\n"
15303                             "layout(triangles, equal_spacing, cw) in;\n"
15304                             "layout(location=0) patch in int x;\n"
15305                             "out gl_PerVertex { vec4 gl_Position; };\n"
15306                             "void main(){\n"
15307                             "   gl_Position.xyz = gl_TessCoord;\n"
15308                             "   gl_Position.w = x;\n"
15309                             "}\n";
15310     char const *fsSource = "#version 450\n"
15311                            "layout(location=0) out vec4 color;\n"
15312                            "void main(){\n"
15313                            "   color = vec4(1);\n"
15314                            "}\n";
15315
15316     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15317     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15318     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15319     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15320
15321     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15322                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15323
15324     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15325
15326     VkPipelineObj pipe(m_device);
15327     pipe.SetInputAssembly(&iasci);
15328     pipe.SetTessellation(&tsci);
15329     pipe.AddColorAttachment();
15330     pipe.AddShader(&vs);
15331     pipe.AddShader(&tcs);
15332     pipe.AddShader(&tes);
15333     pipe.AddShader(&fs);
15334
15335     VkDescriptorSetObj descriptorSet(m_device);
15336     descriptorSet.AppendDummy();
15337     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15338
15339     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15340
15341     m_errorMonitor->VerifyFound();
15342 }
15343
15344 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
15345     TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
15346                      "bindings provide the same location");
15347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15348                                          "Duplicate vertex input binding descriptions for binding 0");
15349
15350     ASSERT_NO_FATAL_FAILURE(InitState());
15351     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15352
15353     /* Two binding descriptions for binding 0 */
15354     VkVertexInputBindingDescription input_bindings[2];
15355     memset(input_bindings, 0, sizeof(input_bindings));
15356
15357     VkVertexInputAttributeDescription input_attrib;
15358     memset(&input_attrib, 0, sizeof(input_attrib));
15359     input_attrib.format = VK_FORMAT_R32_SFLOAT;
15360
15361     char const *vsSource = "#version 450\n"
15362                            "\n"
15363                            "layout(location=0) in float x;\n" /* attrib provided float */
15364                            "out gl_PerVertex {\n"
15365                            "    vec4 gl_Position;\n"
15366                            "};\n"
15367                            "void main(){\n"
15368                            "   gl_Position = vec4(x);\n"
15369                            "}\n";
15370     char const *fsSource = "#version 450\n"
15371                            "\n"
15372                            "layout(location=0) out vec4 color;\n"
15373                            "void main(){\n"
15374                            "   color = vec4(1);\n"
15375                            "}\n";
15376
15377     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15378     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15379
15380     VkPipelineObj pipe(m_device);
15381     pipe.AddColorAttachment();
15382     pipe.AddShader(&vs);
15383     pipe.AddShader(&fs);
15384
15385     pipe.AddVertexInputBindings(input_bindings, 2);
15386     pipe.AddVertexInputAttribs(&input_attrib, 1);
15387
15388     VkDescriptorSetObj descriptorSet(m_device);
15389     descriptorSet.AppendDummy();
15390     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15391
15392     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15393
15394     m_errorMonitor->VerifyFound();
15395 }
15396
15397 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
15398     TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
15399                      "attributes. This is interesting because they consume multiple "
15400                      "locations.");
15401     m_errorMonitor->ExpectSuccess();
15402
15403     ASSERT_NO_FATAL_FAILURE(InitState());
15404     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15405
15406     if (!m_device->phy().features().shaderFloat64) {
15407         printf("Device does not support 64bit vertex attributes; skipped.\n");
15408         return;
15409     }
15410
15411     VkVertexInputBindingDescription input_bindings[1];
15412     memset(input_bindings, 0, sizeof(input_bindings));
15413
15414     VkVertexInputAttributeDescription input_attribs[4];
15415     memset(input_attribs, 0, sizeof(input_attribs));
15416     input_attribs[0].location = 0;
15417     input_attribs[0].offset = 0;
15418     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15419     input_attribs[1].location = 2;
15420     input_attribs[1].offset = 32;
15421     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15422     input_attribs[2].location = 4;
15423     input_attribs[2].offset = 64;
15424     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15425     input_attribs[3].location = 6;
15426     input_attribs[3].offset = 96;
15427     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15428
15429     char const *vsSource = "#version 450\n"
15430                            "\n"
15431                            "layout(location=0) in dmat4 x;\n"
15432                            "out gl_PerVertex {\n"
15433                            "    vec4 gl_Position;\n"
15434                            "};\n"
15435                            "void main(){\n"
15436                            "   gl_Position = vec4(x[0][0]);\n"
15437                            "}\n";
15438     char const *fsSource = "#version 450\n"
15439                            "\n"
15440                            "layout(location=0) out vec4 color;\n"
15441                            "void main(){\n"
15442                            "   color = vec4(1);\n"
15443                            "}\n";
15444
15445     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15446     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15447
15448     VkPipelineObj pipe(m_device);
15449     pipe.AddColorAttachment();
15450     pipe.AddShader(&vs);
15451     pipe.AddShader(&fs);
15452
15453     pipe.AddVertexInputBindings(input_bindings, 1);
15454     pipe.AddVertexInputAttribs(input_attribs, 4);
15455
15456     VkDescriptorSetObj descriptorSet(m_device);
15457     descriptorSet.AppendDummy();
15458     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15459
15460     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15461
15462     m_errorMonitor->VerifyNotFound();
15463 }
15464
15465 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
15466     TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
15467                      "provide an output for one of the pipeline's color attachments");
15468     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
15469
15470     ASSERT_NO_FATAL_FAILURE(InitState());
15471
15472     char const *vsSource = "#version 450\n"
15473                            "\n"
15474                            "out gl_PerVertex {\n"
15475                            "    vec4 gl_Position;\n"
15476                            "};\n"
15477                            "void main(){\n"
15478                            "   gl_Position = vec4(1);\n"
15479                            "}\n";
15480     char const *fsSource = "#version 450\n"
15481                            "\n"
15482                            "void main(){\n"
15483                            "}\n";
15484
15485     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15486     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15487
15488     VkPipelineObj pipe(m_device);
15489     pipe.AddShader(&vs);
15490     pipe.AddShader(&fs);
15491
15492     /* set up CB 0, not written */
15493     pipe.AddColorAttachment();
15494     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15495
15496     VkDescriptorSetObj descriptorSet(m_device);
15497     descriptorSet.AppendDummy();
15498     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15499
15500     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15501
15502     m_errorMonitor->VerifyFound();
15503 }
15504
15505 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
15506     TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
15507                      "output with no matching attachment");
15508     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
15509                                          "FS writes to output location 1 with no matching attachment");
15510
15511     ASSERT_NO_FATAL_FAILURE(InitState());
15512
15513     char const *vsSource = "#version 450\n"
15514                            "\n"
15515                            "out gl_PerVertex {\n"
15516                            "    vec4 gl_Position;\n"
15517                            "};\n"
15518                            "void main(){\n"
15519                            "   gl_Position = vec4(1);\n"
15520                            "}\n";
15521     char const *fsSource = "#version 450\n"
15522                            "\n"
15523                            "layout(location=0) out vec4 x;\n"
15524                            "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
15525                            "void main(){\n"
15526                            "   x = vec4(1);\n"
15527                            "   y = vec4(1);\n"
15528                            "}\n";
15529
15530     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15531     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15532
15533     VkPipelineObj pipe(m_device);
15534     pipe.AddShader(&vs);
15535     pipe.AddShader(&fs);
15536
15537     /* set up CB 0, not written */
15538     pipe.AddColorAttachment();
15539     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15540     /* FS writes CB 1, but we don't configure it */
15541
15542     VkDescriptorSetObj descriptorSet(m_device);
15543     descriptorSet.AppendDummy();
15544     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15545
15546     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15547
15548     m_errorMonitor->VerifyFound();
15549 }
15550
15551 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
15552     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
15553                      "type of an FS output variable, and the format of the corresponding attachment");
15554     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
15555
15556     ASSERT_NO_FATAL_FAILURE(InitState());
15557
15558     char const *vsSource = "#version 450\n"
15559                            "\n"
15560                            "out gl_PerVertex {\n"
15561                            "    vec4 gl_Position;\n"
15562                            "};\n"
15563                            "void main(){\n"
15564                            "   gl_Position = vec4(1);\n"
15565                            "}\n";
15566     char const *fsSource = "#version 450\n"
15567                            "\n"
15568                            "layout(location=0) out ivec4 x;\n" /* not UNORM */
15569                            "void main(){\n"
15570                            "   x = ivec4(1);\n"
15571                            "}\n";
15572
15573     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15574     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15575
15576     VkPipelineObj pipe(m_device);
15577     pipe.AddShader(&vs);
15578     pipe.AddShader(&fs);
15579
15580     /* set up CB 0; type is UNORM by default */
15581     pipe.AddColorAttachment();
15582     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15583
15584     VkDescriptorSetObj descriptorSet(m_device);
15585     descriptorSet.AppendDummy();
15586     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15587
15588     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15589
15590     m_errorMonitor->VerifyFound();
15591 }
15592
15593 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
15594     TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
15595                      "block which has no corresponding binding in the pipeline layout");
15596     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
15597
15598     ASSERT_NO_FATAL_FAILURE(InitState());
15599
15600     char const *vsSource = "#version 450\n"
15601                            "\n"
15602                            "out gl_PerVertex {\n"
15603                            "    vec4 gl_Position;\n"
15604                            "};\n"
15605                            "void main(){\n"
15606                            "   gl_Position = vec4(1);\n"
15607                            "}\n";
15608     char const *fsSource = "#version 450\n"
15609                            "\n"
15610                            "layout(location=0) out vec4 x;\n"
15611                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
15612                            "void main(){\n"
15613                            "   x = vec4(bar.y);\n"
15614                            "}\n";
15615
15616     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15617     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15618
15619     VkPipelineObj pipe(m_device);
15620     pipe.AddShader(&vs);
15621     pipe.AddShader(&fs);
15622
15623     /* set up CB 0; type is UNORM by default */
15624     pipe.AddColorAttachment();
15625     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15626
15627     VkDescriptorSetObj descriptorSet(m_device);
15628     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15629
15630     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15631
15632     m_errorMonitor->VerifyFound();
15633 }
15634
15635 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
15636     TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
15637                      "which are not provided in the pipeline layout");
15638     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
15639
15640     ASSERT_NO_FATAL_FAILURE(InitState());
15641
15642     char const *vsSource = "#version 450\n"
15643                            "\n"
15644                            "layout(push_constant, std430) uniform foo { float x; } consts;\n"
15645                            "out gl_PerVertex {\n"
15646                            "    vec4 gl_Position;\n"
15647                            "};\n"
15648                            "void main(){\n"
15649                            "   gl_Position = vec4(consts.x);\n"
15650                            "}\n";
15651     char const *fsSource = "#version 450\n"
15652                            "\n"
15653                            "layout(location=0) out vec4 x;\n"
15654                            "void main(){\n"
15655                            "   x = vec4(1);\n"
15656                            "}\n";
15657
15658     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15659     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15660
15661     VkPipelineObj pipe(m_device);
15662     pipe.AddShader(&vs);
15663     pipe.AddShader(&fs);
15664
15665     /* set up CB 0; type is UNORM by default */
15666     pipe.AddColorAttachment();
15667     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15668
15669     VkDescriptorSetObj descriptorSet(m_device);
15670     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15671
15672     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15673
15674     /* should have generated an error -- no push constant ranges provided! */
15675     m_errorMonitor->VerifyFound();
15676 }
15677
15678 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
15679     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15680                      "which is not included in the subpass description");
15681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15682                                          "consumes input attachment index 0 but not provided in subpass");
15683
15684     ASSERT_NO_FATAL_FAILURE(InitState());
15685
15686     char const *vsSource = "#version 450\n"
15687                            "\n"
15688                            "out gl_PerVertex {\n"
15689                            "    vec4 gl_Position;\n"
15690                            "};\n"
15691                            "void main(){\n"
15692                            "    gl_Position = vec4(1);\n"
15693                            "}\n";
15694     char const *fsSource = "#version 450\n"
15695                            "\n"
15696                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15697                            "layout(location=0) out vec4 color;\n"
15698                            "void main() {\n"
15699                            "   color = subpassLoad(x);\n"
15700                            "}\n";
15701
15702     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15703     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15704
15705     VkPipelineObj pipe(m_device);
15706     pipe.AddShader(&vs);
15707     pipe.AddShader(&fs);
15708     pipe.AddColorAttachment();
15709     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15710
15711     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15712     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15713     VkDescriptorSetLayout dsl;
15714     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15715     ASSERT_VK_SUCCESS(err);
15716
15717     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15718     VkPipelineLayout pl;
15719     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15720     ASSERT_VK_SUCCESS(err);
15721
15722     // error here.
15723     pipe.CreateVKPipeline(pl, renderPass());
15724
15725     m_errorMonitor->VerifyFound();
15726
15727     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15728     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15729 }
15730
15731 TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
15732     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
15733     m_errorMonitor->ExpectSuccess();
15734
15735     ASSERT_NO_FATAL_FAILURE(InitState());
15736
15737     char const *vsSource = "#version 450\n"
15738                            "\n"
15739                            "out gl_PerVertex {\n"
15740                            "    vec4 gl_Position;\n"
15741                            "};\n"
15742                            "void main(){\n"
15743                            "    gl_Position = vec4(1);\n"
15744                            "}\n";
15745     char const *fsSource = "#version 450\n"
15746                            "\n"
15747                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15748                            "layout(location=0) out vec4 color;\n"
15749                            "void main() {\n"
15750                            "   color = subpassLoad(x);\n"
15751                            "}\n";
15752
15753     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15754     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15755
15756     VkPipelineObj pipe(m_device);
15757     pipe.AddShader(&vs);
15758     pipe.AddShader(&fs);
15759     pipe.AddColorAttachment();
15760     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15761
15762     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15763     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15764     VkDescriptorSetLayout dsl;
15765     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15766     ASSERT_VK_SUCCESS(err);
15767
15768     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15769     VkPipelineLayout pl;
15770     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15771     ASSERT_VK_SUCCESS(err);
15772
15773     VkAttachmentDescription descs[2] = {
15774         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15775          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15776          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15777         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15778          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15779     };
15780     VkAttachmentReference color = {
15781         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15782     };
15783     VkAttachmentReference input = {
15784         1, VK_IMAGE_LAYOUT_GENERAL,
15785     };
15786
15787     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15788
15789     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15790     VkRenderPass rp;
15791     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15792     ASSERT_VK_SUCCESS(err);
15793
15794     // should be OK. would go wrong here if it's going to...
15795     pipe.CreateVKPipeline(pl, rp);
15796
15797     m_errorMonitor->VerifyNotFound();
15798
15799     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15800     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15801     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15802 }
15803
15804 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
15805     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15806                      "with a format having a different fundamental type");
15807     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15808                                          "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
15809
15810     ASSERT_NO_FATAL_FAILURE(InitState());
15811
15812     char const *vsSource = "#version 450\n"
15813                            "\n"
15814                            "out gl_PerVertex {\n"
15815                            "    vec4 gl_Position;\n"
15816                            "};\n"
15817                            "void main(){\n"
15818                            "    gl_Position = vec4(1);\n"
15819                            "}\n";
15820     char const *fsSource = "#version 450\n"
15821                            "\n"
15822                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15823                            "layout(location=0) out vec4 color;\n"
15824                            "void main() {\n"
15825                            "   color = subpassLoad(x);\n"
15826                            "}\n";
15827
15828     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15829     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15830
15831     VkPipelineObj pipe(m_device);
15832     pipe.AddShader(&vs);
15833     pipe.AddShader(&fs);
15834     pipe.AddColorAttachment();
15835     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15836
15837     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15838     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15839     VkDescriptorSetLayout dsl;
15840     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15841     ASSERT_VK_SUCCESS(err);
15842
15843     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15844     VkPipelineLayout pl;
15845     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15846     ASSERT_VK_SUCCESS(err);
15847
15848     VkAttachmentDescription descs[2] = {
15849         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15850          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15851          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15852         {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15853          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15854     };
15855     VkAttachmentReference color = {
15856         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15857     };
15858     VkAttachmentReference input = {
15859         1, VK_IMAGE_LAYOUT_GENERAL,
15860     };
15861
15862     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15863
15864     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15865     VkRenderPass rp;
15866     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15867     ASSERT_VK_SUCCESS(err);
15868
15869     // error here.
15870     pipe.CreateVKPipeline(pl, rp);
15871
15872     m_errorMonitor->VerifyFound();
15873
15874     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15875     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15876     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15877 }
15878
15879 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
15880     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15881                      "which is not included in the subpass description -- array case");
15882     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15883                                          "consumes input attachment index 1 but not provided in subpass");
15884
15885     ASSERT_NO_FATAL_FAILURE(InitState());
15886
15887     char const *vsSource = "#version 450\n"
15888                            "\n"
15889                            "out gl_PerVertex {\n"
15890                            "    vec4 gl_Position;\n"
15891                            "};\n"
15892                            "void main(){\n"
15893                            "    gl_Position = vec4(1);\n"
15894                            "}\n";
15895     char const *fsSource = "#version 450\n"
15896                            "\n"
15897                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n"
15898                            "layout(location=0) out vec4 color;\n"
15899                            "void main() {\n"
15900                            "   color = subpassLoad(xs[1]);\n"
15901                            "}\n";
15902
15903     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15904     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15905
15906     VkPipelineObj pipe(m_device);
15907     pipe.AddShader(&vs);
15908     pipe.AddShader(&fs);
15909     pipe.AddColorAttachment();
15910     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15911
15912     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15913     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15914     VkDescriptorSetLayout dsl;
15915     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15916     ASSERT_VK_SUCCESS(err);
15917
15918     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15919     VkPipelineLayout pl;
15920     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15921     ASSERT_VK_SUCCESS(err);
15922
15923     // error here.
15924     pipe.CreateVKPipeline(pl, renderPass());
15925
15926     m_errorMonitor->VerifyFound();
15927
15928     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15929     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15930 }
15931
15932 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
15933     TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
15934                      "descriptor which is not provided in the pipeline layout");
15935     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
15936
15937     ASSERT_NO_FATAL_FAILURE(InitState());
15938
15939     char const *csSource = "#version 450\n"
15940                            "\n"
15941                            "layout(local_size_x=1) in;\n"
15942                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15943                            "void main(){\n"
15944                            "   x = vec4(1);\n"
15945                            "}\n";
15946
15947     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15948
15949     VkDescriptorSetObj descriptorSet(m_device);
15950     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15951
15952     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15953                                         nullptr,
15954                                         0,
15955                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15956                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15957                                         descriptorSet.GetPipelineLayout(),
15958                                         VK_NULL_HANDLE,
15959                                         -1};
15960
15961     VkPipeline pipe;
15962     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
15963
15964     m_errorMonitor->VerifyFound();
15965
15966     if (err == VK_SUCCESS) {
15967         vkDestroyPipeline(m_device->device(), pipe, nullptr);
15968     }
15969 }
15970
15971 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
15972     TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
15973                      "descriptor-backed resource which is not provided, but the shader does not "
15974                      "statically use it. This is interesting because it requires compute pipelines "
15975                      "to have a proper descriptor use walk, which they didn't for some time.");
15976     m_errorMonitor->ExpectSuccess();
15977
15978     ASSERT_NO_FATAL_FAILURE(InitState());
15979
15980     char const *csSource = "#version 450\n"
15981                            "\n"
15982                            "layout(local_size_x=1) in;\n"
15983                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15984                            "void main(){\n"
15985                            "   // x is not used.\n"
15986                            "}\n";
15987
15988     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15989
15990     VkDescriptorSetObj descriptorSet(m_device);
15991     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15992
15993     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15994                                         nullptr,
15995                                         0,
15996                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15997                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15998                                         descriptorSet.GetPipelineLayout(),
15999                                         VK_NULL_HANDLE,
16000                                         -1};
16001
16002     VkPipeline pipe;
16003     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16004
16005     m_errorMonitor->VerifyNotFound();
16006
16007     if (err == VK_SUCCESS) {
16008         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16009     }
16010 }
16011
16012 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
16013     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
16014                      "descriptor-backed resource of a mismatched type");
16015     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16016                                          "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
16017
16018     ASSERT_NO_FATAL_FAILURE(InitState());
16019
16020     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
16021     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding};
16022     VkDescriptorSetLayout dsl;
16023     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16024     ASSERT_VK_SUCCESS(err);
16025
16026     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16027     VkPipelineLayout pl;
16028     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16029     ASSERT_VK_SUCCESS(err);
16030
16031     char const *csSource = "#version 450\n"
16032                            "\n"
16033                            "layout(local_size_x=1) in;\n"
16034                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
16035                            "void main() {\n"
16036                            "   x.x = 1.0f;\n"
16037                            "}\n";
16038     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16039
16040     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16041                                         nullptr,
16042                                         0,
16043                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16044                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16045                                         pl,
16046                                         VK_NULL_HANDLE,
16047                                         -1};
16048
16049     VkPipeline pipe;
16050     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16051
16052     m_errorMonitor->VerifyFound();
16053
16054     if (err == VK_SUCCESS) {
16055         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16056     }
16057
16058     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16059     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16060 }
16061
16062 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
16063     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16064                      "sampler portion of a combined image + sampler");
16065     m_errorMonitor->ExpectSuccess();
16066
16067     ASSERT_NO_FATAL_FAILURE(InitState());
16068
16069     VkDescriptorSetLayoutBinding bindings[] = {
16070         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16071         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16072         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16073     };
16074     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16075     VkDescriptorSetLayout dsl;
16076     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16077     ASSERT_VK_SUCCESS(err);
16078
16079     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16080     VkPipelineLayout pl;
16081     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16082     ASSERT_VK_SUCCESS(err);
16083
16084     char const *csSource = "#version 450\n"
16085                            "\n"
16086                            "layout(local_size_x=1) in;\n"
16087                            "layout(set=0, binding=0) uniform sampler s;\n"
16088                            "layout(set=0, binding=1) uniform texture2D t;\n"
16089                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16090                            "void main() {\n"
16091                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16092                            "}\n";
16093     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16094
16095     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16096                                         nullptr,
16097                                         0,
16098                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16099                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16100                                         pl,
16101                                         VK_NULL_HANDLE,
16102                                         -1};
16103
16104     VkPipeline pipe;
16105     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16106
16107     m_errorMonitor->VerifyNotFound();
16108
16109     if (err == VK_SUCCESS) {
16110         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16111     }
16112
16113     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16114     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16115 }
16116
16117 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
16118     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16119                      "image portion of a combined image + sampler");
16120     m_errorMonitor->ExpectSuccess();
16121
16122     ASSERT_NO_FATAL_FAILURE(InitState());
16123
16124     VkDescriptorSetLayoutBinding bindings[] = {
16125         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16126         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16127         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16128     };
16129     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16130     VkDescriptorSetLayout dsl;
16131     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16132     ASSERT_VK_SUCCESS(err);
16133
16134     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16135     VkPipelineLayout pl;
16136     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16137     ASSERT_VK_SUCCESS(err);
16138
16139     char const *csSource = "#version 450\n"
16140                            "\n"
16141                            "layout(local_size_x=1) in;\n"
16142                            "layout(set=0, binding=0) uniform texture2D t;\n"
16143                            "layout(set=0, binding=1) uniform sampler s;\n"
16144                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16145                            "void main() {\n"
16146                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16147                            "}\n";
16148     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16149
16150     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16151                                         nullptr,
16152                                         0,
16153                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16154                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16155                                         pl,
16156                                         VK_NULL_HANDLE,
16157                                         -1};
16158
16159     VkPipeline pipe;
16160     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16161
16162     m_errorMonitor->VerifyNotFound();
16163
16164     if (err == VK_SUCCESS) {
16165         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16166     }
16167
16168     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16169     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16170 }
16171
16172 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
16173     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
16174                      "both the sampler and the image of a combined image+sampler "
16175                      "but via separate variables");
16176     m_errorMonitor->ExpectSuccess();
16177
16178     ASSERT_NO_FATAL_FAILURE(InitState());
16179
16180     VkDescriptorSetLayoutBinding bindings[] = {
16181         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16182         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16183     };
16184     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
16185     VkDescriptorSetLayout dsl;
16186     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16187     ASSERT_VK_SUCCESS(err);
16188
16189     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16190     VkPipelineLayout pl;
16191     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16192     ASSERT_VK_SUCCESS(err);
16193
16194     char const *csSource = "#version 450\n"
16195                            "\n"
16196                            "layout(local_size_x=1) in;\n"
16197                            "layout(set=0, binding=0) uniform texture2D t;\n"
16198                            "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
16199                            "layout(set=0, binding=1) buffer block { vec4 x; };\n"
16200                            "void main() {\n"
16201                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16202                            "}\n";
16203     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16204
16205     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16206                                         nullptr,
16207                                         0,
16208                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16209                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16210                                         pl,
16211                                         VK_NULL_HANDLE,
16212                                         -1};
16213
16214     VkPipeline pipe;
16215     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16216
16217     m_errorMonitor->VerifyNotFound();
16218
16219     if (err == VK_SUCCESS) {
16220         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16221     }
16222
16223     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16224     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16225 }
16226
16227 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
16228     TEST_DESCRIPTION("Test that an error is produced when an image view type "
16229                      "does not match the dimensionality declared in the shader");
16230
16231     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
16232
16233     ASSERT_NO_FATAL_FAILURE(InitState());
16234     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16235
16236     char const *vsSource = "#version 450\n"
16237                            "\n"
16238                            "out gl_PerVertex { vec4 gl_Position; };\n"
16239                            "void main() { gl_Position = vec4(0); }\n";
16240     char const *fsSource = "#version 450\n"
16241                            "\n"
16242                            "layout(set=0, binding=0) uniform sampler3D s;\n"
16243                            "layout(location=0) out vec4 color;\n"
16244                            "void main() {\n"
16245                            "   color = texture(s, vec3(0));\n"
16246                            "}\n";
16247     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16248     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16249
16250     VkPipelineObj pipe(m_device);
16251     pipe.AddShader(&vs);
16252     pipe.AddShader(&fs);
16253     pipe.AddColorAttachment();
16254
16255     VkTextureObj texture(m_device, nullptr);
16256     VkSamplerObj sampler(m_device);
16257
16258     VkDescriptorSetObj descriptorSet(m_device);
16259     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16260     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16261
16262     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16263     ASSERT_VK_SUCCESS(err);
16264
16265     BeginCommandBuffer();
16266
16267     m_commandBuffer->BindPipeline(pipe);
16268     m_commandBuffer->BindDescriptorSet(descriptorSet);
16269
16270     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16271     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16272     VkRect2D scissor = {{0, 0}, {16, 16}};
16273     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16274
16275     // error produced here.
16276     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16277
16278     m_errorMonitor->VerifyFound();
16279
16280     EndCommandBuffer();
16281 }
16282
16283 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
16284     TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
16285                      "are consumed via singlesample images types in the shader, or vice versa.");
16286
16287     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
16288
16289     ASSERT_NO_FATAL_FAILURE(InitState());
16290     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16291
16292     char const *vsSource = "#version 450\n"
16293                            "\n"
16294                            "out gl_PerVertex { vec4 gl_Position; };\n"
16295                            "void main() { gl_Position = vec4(0); }\n";
16296     char const *fsSource = "#version 450\n"
16297                            "\n"
16298                            "layout(set=0, binding=0) uniform sampler2DMS s;\n"
16299                            "layout(location=0) out vec4 color;\n"
16300                            "void main() {\n"
16301                            "   color = texelFetch(s, ivec2(0), 0);\n"
16302                            "}\n";
16303     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16304     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16305
16306     VkPipelineObj pipe(m_device);
16307     pipe.AddShader(&vs);
16308     pipe.AddShader(&fs);
16309     pipe.AddColorAttachment();
16310
16311     VkTextureObj texture(m_device, nullptr);
16312     VkSamplerObj sampler(m_device);
16313
16314     VkDescriptorSetObj descriptorSet(m_device);
16315     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16316     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16317
16318     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16319     ASSERT_VK_SUCCESS(err);
16320
16321     BeginCommandBuffer();
16322
16323     m_commandBuffer->BindPipeline(pipe);
16324     m_commandBuffer->BindDescriptorSet(descriptorSet);
16325
16326     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16327     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16328     VkRect2D scissor = {{0, 0}, {16, 16}};
16329     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16330
16331     // error produced here.
16332     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16333
16334     m_errorMonitor->VerifyFound();
16335
16336     EndCommandBuffer();
16337 }
16338
16339 #endif // SHADER_CHECKER_TESTS
16340
16341 #if DEVICE_LIMITS_TESTS
16342 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) {
16343     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16344
16345     ASSERT_NO_FATAL_FAILURE(InitState());
16346
16347     // Create an image
16348     VkImage image;
16349
16350     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16351     const int32_t tex_width = 32;
16352     const int32_t tex_height = 32;
16353
16354     VkImageCreateInfo image_create_info = {};
16355     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16356     image_create_info.pNext = NULL;
16357     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16358     image_create_info.format = tex_format;
16359     image_create_info.extent.width = tex_width;
16360     image_create_info.extent.height = tex_height;
16361     image_create_info.extent.depth = 1;
16362     image_create_info.mipLevels = 1;
16363     image_create_info.arrayLayers = 1;
16364     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16365     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16366     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16367     image_create_info.flags = 0;
16368
16369     // Introduce error by sending down a bogus width extent
16370     image_create_info.extent.width = 65536;
16371     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16372
16373     m_errorMonitor->VerifyFound();
16374 }
16375
16376 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) {
16377     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16378                                          "CreateImage extents is 0 for at least one required dimension");
16379
16380     ASSERT_NO_FATAL_FAILURE(InitState());
16381
16382     // Create an image
16383     VkImage image;
16384
16385     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16386     const int32_t tex_width = 32;
16387     const int32_t tex_height = 32;
16388
16389     VkImageCreateInfo image_create_info = {};
16390     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16391     image_create_info.pNext = NULL;
16392     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16393     image_create_info.format = tex_format;
16394     image_create_info.extent.width = tex_width;
16395     image_create_info.extent.height = tex_height;
16396     image_create_info.extent.depth = 1;
16397     image_create_info.mipLevels = 1;
16398     image_create_info.arrayLayers = 1;
16399     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16400     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16401     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16402     image_create_info.flags = 0;
16403
16404     // Introduce error by sending down a bogus width extent
16405     image_create_info.extent.width = 0;
16406     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16407
16408     m_errorMonitor->VerifyFound();
16409 }
16410 #endif // DEVICE_LIMITS_TESTS
16411
16412 #if IMAGE_TESTS
16413 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
16414     TEST_DESCRIPTION("Create a render pass with an attachment description "
16415                      "format set to VK_FORMAT_UNDEFINED");
16416
16417     ASSERT_NO_FATAL_FAILURE(InitState());
16418     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16419
16420     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
16421
16422     VkAttachmentReference color_attach = {};
16423     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
16424     color_attach.attachment = 0;
16425     VkSubpassDescription subpass = {};
16426     subpass.colorAttachmentCount = 1;
16427     subpass.pColorAttachments = &color_attach;
16428
16429     VkRenderPassCreateInfo rpci = {};
16430     rpci.subpassCount = 1;
16431     rpci.pSubpasses = &subpass;
16432     rpci.attachmentCount = 1;
16433     VkAttachmentDescription attach_desc = {};
16434     attach_desc.format = VK_FORMAT_UNDEFINED;
16435     rpci.pAttachments = &attach_desc;
16436     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16437     VkRenderPass rp;
16438     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16439
16440     m_errorMonitor->VerifyFound();
16441
16442     if (result == VK_SUCCESS) {
16443         vkDestroyRenderPass(m_device->device(), rp, NULL);
16444     }
16445 }
16446
16447 TEST_F(VkLayerTest, InvalidImageView) {
16448     VkResult err;
16449
16450     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 ");
16451
16452     ASSERT_NO_FATAL_FAILURE(InitState());
16453
16454     // Create an image and try to create a view with bad baseMipLevel
16455     VkImage image;
16456
16457     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16458     const int32_t tex_width = 32;
16459     const int32_t tex_height = 32;
16460
16461     VkImageCreateInfo image_create_info = {};
16462     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16463     image_create_info.pNext = NULL;
16464     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16465     image_create_info.format = tex_format;
16466     image_create_info.extent.width = tex_width;
16467     image_create_info.extent.height = tex_height;
16468     image_create_info.extent.depth = 1;
16469     image_create_info.mipLevels = 1;
16470     image_create_info.arrayLayers = 1;
16471     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16472     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16473     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16474     image_create_info.flags = 0;
16475
16476     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16477     ASSERT_VK_SUCCESS(err);
16478
16479     VkImageViewCreateInfo image_view_create_info = {};
16480     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16481     image_view_create_info.image = image;
16482     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16483     image_view_create_info.format = tex_format;
16484     image_view_create_info.subresourceRange.layerCount = 1;
16485     image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error
16486     image_view_create_info.subresourceRange.levelCount = 1;
16487     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16488
16489     VkImageView view;
16490     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16491
16492     m_errorMonitor->VerifyFound();
16493     vkDestroyImage(m_device->device(), image, NULL);
16494 }
16495
16496 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
16497     VkResult err;
16498     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16499                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
16500
16501     ASSERT_NO_FATAL_FAILURE(InitState());
16502
16503     // Create an image and try to create a view with no memory backing the image
16504     VkImage image;
16505
16506     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16507     const int32_t tex_width = 32;
16508     const int32_t tex_height = 32;
16509
16510     VkImageCreateInfo image_create_info = {};
16511     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16512     image_create_info.pNext = NULL;
16513     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16514     image_create_info.format = tex_format;
16515     image_create_info.extent.width = tex_width;
16516     image_create_info.extent.height = tex_height;
16517     image_create_info.extent.depth = 1;
16518     image_create_info.mipLevels = 1;
16519     image_create_info.arrayLayers = 1;
16520     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16521     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16522     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16523     image_create_info.flags = 0;
16524
16525     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16526     ASSERT_VK_SUCCESS(err);
16527
16528     VkImageViewCreateInfo image_view_create_info = {};
16529     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16530     image_view_create_info.image = image;
16531     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16532     image_view_create_info.format = tex_format;
16533     image_view_create_info.subresourceRange.layerCount = 1;
16534     image_view_create_info.subresourceRange.baseMipLevel = 0;
16535     image_view_create_info.subresourceRange.levelCount = 1;
16536     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16537
16538     VkImageView view;
16539     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16540
16541     m_errorMonitor->VerifyFound();
16542     vkDestroyImage(m_device->device(), image, NULL);
16543     // If last error is success, it still created the view, so delete it.
16544     if (err == VK_SUCCESS) {
16545         vkDestroyImageView(m_device->device(), view, NULL);
16546     }
16547 }
16548
16549 TEST_F(VkLayerTest, InvalidImageViewAspect) {
16550     TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
16551     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image "
16552                                                                         "formats must have ONLY the "
16553                                                                         "VK_IMAGE_ASPECT_COLOR_BIT set");
16554
16555     ASSERT_NO_FATAL_FAILURE(InitState());
16556
16557     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16558     VkImageObj image(m_device);
16559     image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
16560     ASSERT_TRUE(image.initialized());
16561
16562     VkImageViewCreateInfo image_view_create_info = {};
16563     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16564     image_view_create_info.image = image.handle();
16565     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16566     image_view_create_info.format = tex_format;
16567     image_view_create_info.subresourceRange.baseMipLevel = 0;
16568     image_view_create_info.subresourceRange.levelCount = 1;
16569     // Cause an error by setting an invalid image aspect
16570     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16571
16572     VkImageView view;
16573     vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16574
16575     m_errorMonitor->VerifyFound();
16576 }
16577
16578 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
16579     VkResult err;
16580     bool pass;
16581
16582     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16583                                          "vkCmdCopyImage: number of layers in source and destination subresources for pRegions");
16584
16585     ASSERT_NO_FATAL_FAILURE(InitState());
16586
16587     // Create two images of different types and try to copy between them
16588     VkImage srcImage;
16589     VkImage dstImage;
16590     VkDeviceMemory srcMem;
16591     VkDeviceMemory destMem;
16592     VkMemoryRequirements memReqs;
16593
16594     VkImageCreateInfo image_create_info = {};
16595     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16596     image_create_info.pNext = NULL;
16597     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16598     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16599     image_create_info.extent.width = 32;
16600     image_create_info.extent.height = 32;
16601     image_create_info.extent.depth = 1;
16602     image_create_info.mipLevels = 1;
16603     image_create_info.arrayLayers = 4;
16604     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16605     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16606     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16607     image_create_info.flags = 0;
16608
16609     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
16610     ASSERT_VK_SUCCESS(err);
16611
16612     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
16613     ASSERT_VK_SUCCESS(err);
16614
16615     // Allocate memory
16616     VkMemoryAllocateInfo memAlloc = {};
16617     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16618     memAlloc.pNext = NULL;
16619     memAlloc.allocationSize = 0;
16620     memAlloc.memoryTypeIndex = 0;
16621
16622     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
16623     memAlloc.allocationSize = memReqs.size;
16624     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16625     ASSERT_TRUE(pass);
16626     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
16627     ASSERT_VK_SUCCESS(err);
16628
16629     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
16630     memAlloc.allocationSize = memReqs.size;
16631     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16632     ASSERT_VK_SUCCESS(err);
16633     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
16634     ASSERT_VK_SUCCESS(err);
16635
16636     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
16637     ASSERT_VK_SUCCESS(err);
16638     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
16639     ASSERT_VK_SUCCESS(err);
16640
16641     BeginCommandBuffer();
16642     VkImageCopy copyRegion;
16643     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16644     copyRegion.srcSubresource.mipLevel = 0;
16645     copyRegion.srcSubresource.baseArrayLayer = 0;
16646     copyRegion.srcSubresource.layerCount = 1;
16647     copyRegion.srcOffset.x = 0;
16648     copyRegion.srcOffset.y = 0;
16649     copyRegion.srcOffset.z = 0;
16650     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16651     copyRegion.dstSubresource.mipLevel = 0;
16652     copyRegion.dstSubresource.baseArrayLayer = 0;
16653     // Introduce failure by forcing the dst layerCount to differ from src
16654     copyRegion.dstSubresource.layerCount = 3;
16655     copyRegion.dstOffset.x = 0;
16656     copyRegion.dstOffset.y = 0;
16657     copyRegion.dstOffset.z = 0;
16658     copyRegion.extent.width = 1;
16659     copyRegion.extent.height = 1;
16660     copyRegion.extent.depth = 1;
16661     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
16662     EndCommandBuffer();
16663
16664     m_errorMonitor->VerifyFound();
16665
16666     vkDestroyImage(m_device->device(), srcImage, NULL);
16667     vkDestroyImage(m_device->device(), dstImage, NULL);
16668     vkFreeMemory(m_device->device(), srcMem, NULL);
16669     vkFreeMemory(m_device->device(), destMem, NULL);
16670 }
16671
16672 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
16673
16674     TEST_DESCRIPTION("Creating images with unsuported formats ");
16675
16676     ASSERT_NO_FATAL_FAILURE(InitState());
16677     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16678     VkImageObj image(m_device);
16679     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16680                VK_IMAGE_TILING_OPTIMAL, 0);
16681     ASSERT_TRUE(image.initialized());
16682
16683     // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
16684     VkImageCreateInfo image_create_info;
16685     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16686     image_create_info.pNext = NULL;
16687     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16688     image_create_info.format = VK_FORMAT_UNDEFINED;
16689     image_create_info.extent.width = 32;
16690     image_create_info.extent.height = 32;
16691     image_create_info.extent.depth = 1;
16692     image_create_info.mipLevels = 1;
16693     image_create_info.arrayLayers = 1;
16694     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16695     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16696     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16697     image_create_info.flags = 0;
16698
16699     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16700                                          "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
16701
16702     VkImage localImage;
16703     vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16704     m_errorMonitor->VerifyFound();
16705
16706     VkFormat unsupported = VK_FORMAT_UNDEFINED;
16707     // Look for a format that is COMPLETELY unsupported with this hardware
16708     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
16709         VkFormat format = static_cast<VkFormat>(f);
16710         VkFormatProperties fProps = m_device->format_properties(format);
16711         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
16712             unsupported = format;
16713             break;
16714         }
16715     }
16716
16717     if (unsupported != VK_FORMAT_UNDEFINED) {
16718         image_create_info.format = unsupported;
16719         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
16720
16721         vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16722         m_errorMonitor->VerifyFound();
16723     }
16724 }
16725
16726 TEST_F(VkLayerTest, ImageLayerViewTests) {
16727     VkResult ret;
16728     TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
16729
16730     ASSERT_NO_FATAL_FAILURE(InitState());
16731
16732     VkImageObj image(m_device);
16733     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16734                VK_IMAGE_TILING_OPTIMAL, 0);
16735     ASSERT_TRUE(image.initialized());
16736
16737     VkImageView imgView;
16738     VkImageViewCreateInfo imgViewInfo = {};
16739     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16740     imgViewInfo.image = image.handle();
16741     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
16742     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16743     imgViewInfo.subresourceRange.layerCount = 1;
16744     imgViewInfo.subresourceRange.baseMipLevel = 0;
16745     imgViewInfo.subresourceRange.levelCount = 1;
16746     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16747
16748     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel");
16749     // View can't have baseMipLevel >= image's mipLevels - Expect
16750     // VIEW_CREATE_ERROR
16751     imgViewInfo.subresourceRange.baseMipLevel = 1;
16752     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16753     m_errorMonitor->VerifyFound();
16754     imgViewInfo.subresourceRange.baseMipLevel = 0;
16755
16756     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer");
16757     // View can't have baseArrayLayer >= image's arraySize - Expect
16758     // VIEW_CREATE_ERROR
16759     imgViewInfo.subresourceRange.baseArrayLayer = 1;
16760     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16761     m_errorMonitor->VerifyFound();
16762     imgViewInfo.subresourceRange.baseArrayLayer = 0;
16763
16764     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16765                                                                         "pCreateInfo->subresourceRange."
16766                                                                         "levelCount");
16767     // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR
16768     imgViewInfo.subresourceRange.levelCount = 0;
16769     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16770     m_errorMonitor->VerifyFound();
16771     imgViewInfo.subresourceRange.levelCount = 1;
16772
16773     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16774                                                                         "pCreateInfo->subresourceRange."
16775                                                                         "layerCount");
16776     // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR
16777     imgViewInfo.subresourceRange.layerCount = 0;
16778     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16779     m_errorMonitor->VerifyFound();
16780     imgViewInfo.subresourceRange.layerCount = 1;
16781
16782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats");
16783     // Can't use depth format for view into color image - Expect INVALID_FORMAT
16784     imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
16785     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16786     m_errorMonitor->VerifyFound();
16787     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16788
16789     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless "
16790                                                                         "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
16791                                                                         "was set on image creation.");
16792     // Same compatibility class but no MUTABLE_FORMAT bit - Expect
16793     // VIEW_CREATE_ERROR
16794     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
16795     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16796     m_errorMonitor->VerifyFound();
16797     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16798
16799     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with "
16800                                                                         "differing formats but they must be "
16801                                                                         "in the same compatibility class.");
16802     // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect
16803     // VIEW_CREATE_ERROR
16804     VkImageCreateInfo mutImgInfo = image.create_info();
16805     VkImage mutImage;
16806     mutImgInfo.format = VK_FORMAT_R8_UINT;
16807     assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
16808     mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
16809     mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
16810     ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage);
16811     ASSERT_VK_SUCCESS(ret);
16812     imgViewInfo.image = mutImage;
16813     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16814     m_errorMonitor->VerifyFound();
16815     imgViewInfo.image = image.handle();
16816     vkDestroyImage(m_device->handle(), mutImage, NULL);
16817 }
16818
16819 TEST_F(VkLayerTest, MiscImageLayerTests) {
16820
16821     TEST_DESCRIPTION("Image layer tests that don't belong elsewhare");
16822
16823     ASSERT_NO_FATAL_FAILURE(InitState());
16824
16825     VkImageObj image(m_device);
16826     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16827                VK_IMAGE_TILING_OPTIMAL, 0);
16828     ASSERT_TRUE(image.initialized());
16829
16830     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero");
16831     vk_testing::Buffer buffer;
16832     VkMemoryPropertyFlags reqs = 0;
16833     buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
16834     VkBufferImageCopy region = {};
16835     region.bufferRowLength = 128;
16836     region.bufferImageHeight = 128;
16837     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16838     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
16839     region.imageSubresource.layerCount = 0;
16840     region.imageExtent.height = 4;
16841     region.imageExtent.width = 4;
16842     region.imageExtent.depth = 1;
16843     m_commandBuffer->BeginCommandBuffer();
16844     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16845                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16846     m_errorMonitor->VerifyFound();
16847     region.imageSubresource.layerCount = 1;
16848
16849     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
16850     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
16851     region.bufferOffset = 6;
16852     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size");
16853     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16854                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16855     m_errorMonitor->VerifyFound();
16856
16857     // BufferOffset must be a multiple of 4
16858     // Introduce failure by setting bufferOffset to a value not divisible by 4
16859     region.bufferOffset = 6;
16860     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4");
16861     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16862                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16863     m_errorMonitor->VerifyFound();
16864
16865     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
16866     region.bufferOffset = 0;
16867     region.imageExtent.height = 128;
16868     region.imageExtent.width = 128;
16869     // Introduce failure by setting bufferRowLength > 0 but less than width
16870     region.bufferRowLength = 64;
16871     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16872                                          "must be zero or greater-than-or-equal-to imageExtent.width");
16873     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16874                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16875     m_errorMonitor->VerifyFound();
16876
16877     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
16878     region.bufferRowLength = 128;
16879     // Introduce failure by setting bufferRowHeight > 0 but less than height
16880     region.bufferImageHeight = 64;
16881     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16882                                          "must be zero or greater-than-or-equal-to imageExtent.height");
16883     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16884                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16885     m_errorMonitor->VerifyFound();
16886
16887     region.bufferImageHeight = 128;
16888     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must "
16889                                                                         "specify only COLOR or DEPTH or "
16890                                                                         "STENCIL");
16891     // Expect MISMATCHED_IMAGE_ASPECT
16892     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16893     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16894                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16895     m_errorMonitor->VerifyFound();
16896     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16897
16898     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16899                                          "If the format of srcImage is a depth, stencil, depth stencil or "
16900                                          "integer-based format then filter must be VK_FILTER_NEAREST");
16901     // Expect INVALID_FILTER
16902     VkImageObj intImage1(m_device);
16903     intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16904     VkImageObj intImage2(m_device);
16905     intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16906     VkImageBlit blitRegion = {};
16907     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16908     blitRegion.srcSubresource.baseArrayLayer = 0;
16909     blitRegion.srcSubresource.layerCount = 1;
16910     blitRegion.srcSubresource.mipLevel = 0;
16911     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16912     blitRegion.dstSubresource.baseArrayLayer = 0;
16913     blitRegion.dstSubresource.layerCount = 1;
16914     blitRegion.dstSubresource.mipLevel = 0;
16915
16916     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16917                    intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR);
16918     m_errorMonitor->VerifyFound();
16919
16920     // Look for NULL-blit warning
16921     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area.");
16922     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16923                    intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR);
16924     m_errorMonitor->VerifyFound();
16925
16926     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers");
16927     VkImageMemoryBarrier img_barrier;
16928     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
16929     img_barrier.pNext = NULL;
16930     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
16931     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
16932     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16933     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16934     img_barrier.image = image.handle();
16935     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16936     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16937     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16938     img_barrier.subresourceRange.baseArrayLayer = 0;
16939     img_barrier.subresourceRange.baseMipLevel = 0;
16940     // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE
16941     img_barrier.subresourceRange.layerCount = 0;
16942     img_barrier.subresourceRange.levelCount = 1;
16943     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
16944                          nullptr, 0, nullptr, 1, &img_barrier);
16945     m_errorMonitor->VerifyFound();
16946     img_barrier.subresourceRange.layerCount = 1;
16947 }
16948
16949 TEST_F(VkLayerTest, ImageFormatLimits) {
16950
16951     TEST_DESCRIPTION("Exceed the limits of image format ");
16952
16953     ASSERT_NO_FATAL_FAILURE(InitState());
16954     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16955     VkImageCreateInfo image_create_info = {};
16956     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16957     image_create_info.pNext = NULL;
16958     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16959     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16960     image_create_info.extent.width = 32;
16961     image_create_info.extent.height = 32;
16962     image_create_info.extent.depth = 1;
16963     image_create_info.mipLevels = 1;
16964     image_create_info.arrayLayers = 1;
16965     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16966     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16967     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16968     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
16969     image_create_info.flags = 0;
16970
16971     VkImage nullImg;
16972     VkImageFormatProperties imgFmtProps;
16973     vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
16974                                              image_create_info.usage, image_create_info.flags, &imgFmtProps);
16975     image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1;
16976     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16977     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16978     m_errorMonitor->VerifyFound();
16979     image_create_info.extent.depth = 1;
16980
16981     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16982     image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
16983     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16984     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16985     m_errorMonitor->VerifyFound();
16986     image_create_info.mipLevels = 1;
16987
16988     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16989     image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
16990     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16991     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16992     m_errorMonitor->VerifyFound();
16993     image_create_info.arrayLayers = 1;
16994
16995     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format");
16996     int samples = imgFmtProps.sampleCounts >> 1;
16997     image_create_info.samples = (VkSampleCountFlagBits)samples;
16998     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16999     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17000     m_errorMonitor->VerifyFound();
17001     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17002
17003     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be "
17004                                                                         "VK_IMAGE_LAYOUT_UNDEFINED or "
17005                                                                         "VK_IMAGE_LAYOUT_PREINITIALIZED");
17006     image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
17007     // Expect INVALID_LAYOUT
17008     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17009     m_errorMonitor->VerifyFound();
17010     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17011 }
17012
17013 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
17014     VkResult err;
17015     bool pass;
17016
17017     // Create color images with different format sizes and try to copy between them
17018     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17019                                          "vkCmdCopyImage called with unmatched source and dest image format sizes");
17020
17021     ASSERT_NO_FATAL_FAILURE(InitState());
17022
17023     // Create two images of different types and try to copy between them
17024     VkImage srcImage;
17025     VkImage dstImage;
17026     VkDeviceMemory srcMem;
17027     VkDeviceMemory destMem;
17028     VkMemoryRequirements memReqs;
17029
17030     VkImageCreateInfo image_create_info = {};
17031     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17032     image_create_info.pNext = NULL;
17033     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17034     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17035     image_create_info.extent.width = 32;
17036     image_create_info.extent.height = 32;
17037     image_create_info.extent.depth = 1;
17038     image_create_info.mipLevels = 1;
17039     image_create_info.arrayLayers = 1;
17040     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17041     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17042     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17043     image_create_info.flags = 0;
17044
17045     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17046     ASSERT_VK_SUCCESS(err);
17047
17048     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17049     // Introduce failure by creating second image with a different-sized format.
17050     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
17051
17052     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17053     ASSERT_VK_SUCCESS(err);
17054
17055     // Allocate memory
17056     VkMemoryAllocateInfo memAlloc = {};
17057     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17058     memAlloc.pNext = NULL;
17059     memAlloc.allocationSize = 0;
17060     memAlloc.memoryTypeIndex = 0;
17061
17062     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17063     memAlloc.allocationSize = memReqs.size;
17064     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17065     ASSERT_TRUE(pass);
17066     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17067     ASSERT_VK_SUCCESS(err);
17068
17069     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17070     memAlloc.allocationSize = memReqs.size;
17071     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17072     ASSERT_TRUE(pass);
17073     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17074     ASSERT_VK_SUCCESS(err);
17075
17076     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17077     ASSERT_VK_SUCCESS(err);
17078     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17079     ASSERT_VK_SUCCESS(err);
17080
17081     BeginCommandBuffer();
17082     VkImageCopy copyRegion;
17083     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17084     copyRegion.srcSubresource.mipLevel = 0;
17085     copyRegion.srcSubresource.baseArrayLayer = 0;
17086     copyRegion.srcSubresource.layerCount = 0;
17087     copyRegion.srcOffset.x = 0;
17088     copyRegion.srcOffset.y = 0;
17089     copyRegion.srcOffset.z = 0;
17090     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17091     copyRegion.dstSubresource.mipLevel = 0;
17092     copyRegion.dstSubresource.baseArrayLayer = 0;
17093     copyRegion.dstSubresource.layerCount = 0;
17094     copyRegion.dstOffset.x = 0;
17095     copyRegion.dstOffset.y = 0;
17096     copyRegion.dstOffset.z = 0;
17097     copyRegion.extent.width = 1;
17098     copyRegion.extent.height = 1;
17099     copyRegion.extent.depth = 1;
17100     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17101     EndCommandBuffer();
17102
17103     m_errorMonitor->VerifyFound();
17104
17105     vkDestroyImage(m_device->device(), srcImage, NULL);
17106     vkDestroyImage(m_device->device(), dstImage, NULL);
17107     vkFreeMemory(m_device->device(), srcMem, NULL);
17108     vkFreeMemory(m_device->device(), destMem, NULL);
17109 }
17110
17111 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
17112     VkResult err;
17113     bool pass;
17114
17115     // Create a color image and a depth/stencil image and try to copy between them
17116     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17117                                          "vkCmdCopyImage called with unmatched source and dest image depth");
17118
17119     ASSERT_NO_FATAL_FAILURE(InitState());
17120
17121     // Create two images of different types and try to copy between them
17122     VkImage srcImage;
17123     VkImage dstImage;
17124     VkDeviceMemory srcMem;
17125     VkDeviceMemory destMem;
17126     VkMemoryRequirements memReqs;
17127
17128     VkImageCreateInfo image_create_info = {};
17129     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17130     image_create_info.pNext = NULL;
17131     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17132     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17133     image_create_info.extent.width = 32;
17134     image_create_info.extent.height = 32;
17135     image_create_info.extent.depth = 1;
17136     image_create_info.mipLevels = 1;
17137     image_create_info.arrayLayers = 1;
17138     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17139     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17140     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17141     image_create_info.flags = 0;
17142
17143     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17144     ASSERT_VK_SUCCESS(err);
17145
17146     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17147
17148     // Introduce failure by creating second image with a depth/stencil format
17149     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17150     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17151     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17152
17153     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17154     ASSERT_VK_SUCCESS(err);
17155
17156     // Allocate memory
17157     VkMemoryAllocateInfo memAlloc = {};
17158     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17159     memAlloc.pNext = NULL;
17160     memAlloc.allocationSize = 0;
17161     memAlloc.memoryTypeIndex = 0;
17162
17163     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17164     memAlloc.allocationSize = memReqs.size;
17165     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17166     ASSERT_TRUE(pass);
17167     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17168     ASSERT_VK_SUCCESS(err);
17169
17170     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17171     memAlloc.allocationSize = memReqs.size;
17172     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17173     ASSERT_TRUE(pass);
17174     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17175     ASSERT_VK_SUCCESS(err);
17176
17177     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17178     ASSERT_VK_SUCCESS(err);
17179     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17180     ASSERT_VK_SUCCESS(err);
17181
17182     BeginCommandBuffer();
17183     VkImageCopy copyRegion;
17184     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17185     copyRegion.srcSubresource.mipLevel = 0;
17186     copyRegion.srcSubresource.baseArrayLayer = 0;
17187     copyRegion.srcSubresource.layerCount = 0;
17188     copyRegion.srcOffset.x = 0;
17189     copyRegion.srcOffset.y = 0;
17190     copyRegion.srcOffset.z = 0;
17191     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17192     copyRegion.dstSubresource.mipLevel = 0;
17193     copyRegion.dstSubresource.baseArrayLayer = 0;
17194     copyRegion.dstSubresource.layerCount = 0;
17195     copyRegion.dstOffset.x = 0;
17196     copyRegion.dstOffset.y = 0;
17197     copyRegion.dstOffset.z = 0;
17198     copyRegion.extent.width = 1;
17199     copyRegion.extent.height = 1;
17200     copyRegion.extent.depth = 1;
17201     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17202     EndCommandBuffer();
17203
17204     m_errorMonitor->VerifyFound();
17205
17206     vkDestroyImage(m_device->device(), srcImage, NULL);
17207     vkDestroyImage(m_device->device(), dstImage, NULL);
17208     vkFreeMemory(m_device->device(), srcMem, NULL);
17209     vkFreeMemory(m_device->device(), destMem, NULL);
17210 }
17211
17212 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
17213     VkResult err;
17214     bool pass;
17215
17216     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17217                                          "vkCmdResolveImage called with source sample count less than 2.");
17218
17219     ASSERT_NO_FATAL_FAILURE(InitState());
17220
17221     // Create two images of sample count 1 and try to Resolve between them
17222     VkImage srcImage;
17223     VkImage dstImage;
17224     VkDeviceMemory srcMem;
17225     VkDeviceMemory destMem;
17226     VkMemoryRequirements memReqs;
17227
17228     VkImageCreateInfo image_create_info = {};
17229     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17230     image_create_info.pNext = NULL;
17231     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17232     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17233     image_create_info.extent.width = 32;
17234     image_create_info.extent.height = 1;
17235     image_create_info.extent.depth = 1;
17236     image_create_info.mipLevels = 1;
17237     image_create_info.arrayLayers = 1;
17238     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17239     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17240     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17241     image_create_info.flags = 0;
17242
17243     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17244     ASSERT_VK_SUCCESS(err);
17245
17246     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17247
17248     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17249     ASSERT_VK_SUCCESS(err);
17250
17251     // Allocate memory
17252     VkMemoryAllocateInfo memAlloc = {};
17253     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17254     memAlloc.pNext = NULL;
17255     memAlloc.allocationSize = 0;
17256     memAlloc.memoryTypeIndex = 0;
17257
17258     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17259     memAlloc.allocationSize = memReqs.size;
17260     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17261     ASSERT_TRUE(pass);
17262     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17263     ASSERT_VK_SUCCESS(err);
17264
17265     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17266     memAlloc.allocationSize = memReqs.size;
17267     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17268     ASSERT_TRUE(pass);
17269     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17270     ASSERT_VK_SUCCESS(err);
17271
17272     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17273     ASSERT_VK_SUCCESS(err);
17274     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17275     ASSERT_VK_SUCCESS(err);
17276
17277     BeginCommandBuffer();
17278     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17279     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17280     // VK_IMAGE_LAYOUT_GENERAL = 1,
17281     VkImageResolve resolveRegion;
17282     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17283     resolveRegion.srcSubresource.mipLevel = 0;
17284     resolveRegion.srcSubresource.baseArrayLayer = 0;
17285     resolveRegion.srcSubresource.layerCount = 1;
17286     resolveRegion.srcOffset.x = 0;
17287     resolveRegion.srcOffset.y = 0;
17288     resolveRegion.srcOffset.z = 0;
17289     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17290     resolveRegion.dstSubresource.mipLevel = 0;
17291     resolveRegion.dstSubresource.baseArrayLayer = 0;
17292     resolveRegion.dstSubresource.layerCount = 1;
17293     resolveRegion.dstOffset.x = 0;
17294     resolveRegion.dstOffset.y = 0;
17295     resolveRegion.dstOffset.z = 0;
17296     resolveRegion.extent.width = 1;
17297     resolveRegion.extent.height = 1;
17298     resolveRegion.extent.depth = 1;
17299     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17300     EndCommandBuffer();
17301
17302     m_errorMonitor->VerifyFound();
17303
17304     vkDestroyImage(m_device->device(), srcImage, NULL);
17305     vkDestroyImage(m_device->device(), dstImage, NULL);
17306     vkFreeMemory(m_device->device(), srcMem, NULL);
17307     vkFreeMemory(m_device->device(), destMem, NULL);
17308 }
17309
17310 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
17311     VkResult err;
17312     bool pass;
17313
17314     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17315                                          "vkCmdResolveImage called with dest sample count greater than 1.");
17316
17317     ASSERT_NO_FATAL_FAILURE(InitState());
17318
17319     // Create two images of sample count 4 and try to Resolve between them
17320     VkImage srcImage;
17321     VkImage dstImage;
17322     VkDeviceMemory srcMem;
17323     VkDeviceMemory destMem;
17324     VkMemoryRequirements memReqs;
17325
17326     VkImageCreateInfo image_create_info = {};
17327     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17328     image_create_info.pNext = NULL;
17329     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17330     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17331     image_create_info.extent.width = 32;
17332     image_create_info.extent.height = 1;
17333     image_create_info.extent.depth = 1;
17334     image_create_info.mipLevels = 1;
17335     image_create_info.arrayLayers = 1;
17336     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
17337     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17338     // Note: Some implementations expect color attachment usage for any
17339     // multisample surface
17340     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17341     image_create_info.flags = 0;
17342
17343     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17344     ASSERT_VK_SUCCESS(err);
17345
17346     // Note: Some implementations expect color attachment usage for any
17347     // multisample surface
17348     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17349
17350     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17351     ASSERT_VK_SUCCESS(err);
17352
17353     // Allocate memory
17354     VkMemoryAllocateInfo memAlloc = {};
17355     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17356     memAlloc.pNext = NULL;
17357     memAlloc.allocationSize = 0;
17358     memAlloc.memoryTypeIndex = 0;
17359
17360     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17361     memAlloc.allocationSize = memReqs.size;
17362     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17363     ASSERT_TRUE(pass);
17364     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17365     ASSERT_VK_SUCCESS(err);
17366
17367     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17368     memAlloc.allocationSize = memReqs.size;
17369     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17370     ASSERT_TRUE(pass);
17371     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17372     ASSERT_VK_SUCCESS(err);
17373
17374     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17375     ASSERT_VK_SUCCESS(err);
17376     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17377     ASSERT_VK_SUCCESS(err);
17378
17379     BeginCommandBuffer();
17380     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17381     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17382     // VK_IMAGE_LAYOUT_GENERAL = 1,
17383     VkImageResolve resolveRegion;
17384     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17385     resolveRegion.srcSubresource.mipLevel = 0;
17386     resolveRegion.srcSubresource.baseArrayLayer = 0;
17387     resolveRegion.srcSubresource.layerCount = 1;
17388     resolveRegion.srcOffset.x = 0;
17389     resolveRegion.srcOffset.y = 0;
17390     resolveRegion.srcOffset.z = 0;
17391     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17392     resolveRegion.dstSubresource.mipLevel = 0;
17393     resolveRegion.dstSubresource.baseArrayLayer = 0;
17394     resolveRegion.dstSubresource.layerCount = 1;
17395     resolveRegion.dstOffset.x = 0;
17396     resolveRegion.dstOffset.y = 0;
17397     resolveRegion.dstOffset.z = 0;
17398     resolveRegion.extent.width = 1;
17399     resolveRegion.extent.height = 1;
17400     resolveRegion.extent.depth = 1;
17401     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17402     EndCommandBuffer();
17403
17404     m_errorMonitor->VerifyFound();
17405
17406     vkDestroyImage(m_device->device(), srcImage, NULL);
17407     vkDestroyImage(m_device->device(), dstImage, NULL);
17408     vkFreeMemory(m_device->device(), srcMem, NULL);
17409     vkFreeMemory(m_device->device(), destMem, NULL);
17410 }
17411
17412 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
17413     VkResult err;
17414     bool pass;
17415
17416     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17417                                          "vkCmdResolveImage called with unmatched source and dest formats.");
17418
17419     ASSERT_NO_FATAL_FAILURE(InitState());
17420
17421     // Create two images of different types and try to copy between them
17422     VkImage srcImage;
17423     VkImage dstImage;
17424     VkDeviceMemory srcMem;
17425     VkDeviceMemory destMem;
17426     VkMemoryRequirements memReqs;
17427
17428     VkImageCreateInfo image_create_info = {};
17429     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17430     image_create_info.pNext = NULL;
17431     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17432     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17433     image_create_info.extent.width = 32;
17434     image_create_info.extent.height = 1;
17435     image_create_info.extent.depth = 1;
17436     image_create_info.mipLevels = 1;
17437     image_create_info.arrayLayers = 1;
17438     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17439     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17440     // Note: Some implementations expect color attachment usage for any
17441     // multisample surface
17442     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17443     image_create_info.flags = 0;
17444
17445     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17446     ASSERT_VK_SUCCESS(err);
17447
17448     // Set format to something other than source image
17449     image_create_info.format = VK_FORMAT_R32_SFLOAT;
17450     // Note: Some implementations expect color attachment usage for any
17451     // multisample surface
17452     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17453     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17454
17455     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17456     ASSERT_VK_SUCCESS(err);
17457
17458     // Allocate memory
17459     VkMemoryAllocateInfo memAlloc = {};
17460     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17461     memAlloc.pNext = NULL;
17462     memAlloc.allocationSize = 0;
17463     memAlloc.memoryTypeIndex = 0;
17464
17465     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17466     memAlloc.allocationSize = memReqs.size;
17467     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17468     ASSERT_TRUE(pass);
17469     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17470     ASSERT_VK_SUCCESS(err);
17471
17472     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17473     memAlloc.allocationSize = memReqs.size;
17474     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17475     ASSERT_TRUE(pass);
17476     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17477     ASSERT_VK_SUCCESS(err);
17478
17479     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17480     ASSERT_VK_SUCCESS(err);
17481     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17482     ASSERT_VK_SUCCESS(err);
17483
17484     BeginCommandBuffer();
17485     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17486     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17487     // VK_IMAGE_LAYOUT_GENERAL = 1,
17488     VkImageResolve resolveRegion;
17489     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17490     resolveRegion.srcSubresource.mipLevel = 0;
17491     resolveRegion.srcSubresource.baseArrayLayer = 0;
17492     resolveRegion.srcSubresource.layerCount = 1;
17493     resolveRegion.srcOffset.x = 0;
17494     resolveRegion.srcOffset.y = 0;
17495     resolveRegion.srcOffset.z = 0;
17496     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17497     resolveRegion.dstSubresource.mipLevel = 0;
17498     resolveRegion.dstSubresource.baseArrayLayer = 0;
17499     resolveRegion.dstSubresource.layerCount = 1;
17500     resolveRegion.dstOffset.x = 0;
17501     resolveRegion.dstOffset.y = 0;
17502     resolveRegion.dstOffset.z = 0;
17503     resolveRegion.extent.width = 1;
17504     resolveRegion.extent.height = 1;
17505     resolveRegion.extent.depth = 1;
17506     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17507     EndCommandBuffer();
17508
17509     m_errorMonitor->VerifyFound();
17510
17511     vkDestroyImage(m_device->device(), srcImage, NULL);
17512     vkDestroyImage(m_device->device(), dstImage, NULL);
17513     vkFreeMemory(m_device->device(), srcMem, NULL);
17514     vkFreeMemory(m_device->device(), destMem, NULL);
17515 }
17516
17517 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
17518     VkResult err;
17519     bool pass;
17520
17521     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17522                                          "vkCmdResolveImage called with unmatched source and dest image types.");
17523
17524     ASSERT_NO_FATAL_FAILURE(InitState());
17525
17526     // Create two images of different types and try to copy between them
17527     VkImage srcImage;
17528     VkImage dstImage;
17529     VkDeviceMemory srcMem;
17530     VkDeviceMemory destMem;
17531     VkMemoryRequirements memReqs;
17532
17533     VkImageCreateInfo image_create_info = {};
17534     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17535     image_create_info.pNext = NULL;
17536     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17537     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17538     image_create_info.extent.width = 32;
17539     image_create_info.extent.height = 1;
17540     image_create_info.extent.depth = 1;
17541     image_create_info.mipLevels = 1;
17542     image_create_info.arrayLayers = 1;
17543     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17544     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17545     // Note: Some implementations expect color attachment usage for any
17546     // multisample surface
17547     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17548     image_create_info.flags = 0;
17549
17550     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17551     ASSERT_VK_SUCCESS(err);
17552
17553     image_create_info.imageType = VK_IMAGE_TYPE_1D;
17554     // Note: Some implementations expect color attachment usage for any
17555     // multisample surface
17556     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17557     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17558
17559     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17560     ASSERT_VK_SUCCESS(err);
17561
17562     // Allocate memory
17563     VkMemoryAllocateInfo memAlloc = {};
17564     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17565     memAlloc.pNext = NULL;
17566     memAlloc.allocationSize = 0;
17567     memAlloc.memoryTypeIndex = 0;
17568
17569     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17570     memAlloc.allocationSize = memReqs.size;
17571     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17572     ASSERT_TRUE(pass);
17573     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17574     ASSERT_VK_SUCCESS(err);
17575
17576     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17577     memAlloc.allocationSize = memReqs.size;
17578     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17579     ASSERT_TRUE(pass);
17580     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17581     ASSERT_VK_SUCCESS(err);
17582
17583     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17584     ASSERT_VK_SUCCESS(err);
17585     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17586     ASSERT_VK_SUCCESS(err);
17587
17588     BeginCommandBuffer();
17589     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17590     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17591     // VK_IMAGE_LAYOUT_GENERAL = 1,
17592     VkImageResolve resolveRegion;
17593     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17594     resolveRegion.srcSubresource.mipLevel = 0;
17595     resolveRegion.srcSubresource.baseArrayLayer = 0;
17596     resolveRegion.srcSubresource.layerCount = 1;
17597     resolveRegion.srcOffset.x = 0;
17598     resolveRegion.srcOffset.y = 0;
17599     resolveRegion.srcOffset.z = 0;
17600     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17601     resolveRegion.dstSubresource.mipLevel = 0;
17602     resolveRegion.dstSubresource.baseArrayLayer = 0;
17603     resolveRegion.dstSubresource.layerCount = 1;
17604     resolveRegion.dstOffset.x = 0;
17605     resolveRegion.dstOffset.y = 0;
17606     resolveRegion.dstOffset.z = 0;
17607     resolveRegion.extent.width = 1;
17608     resolveRegion.extent.height = 1;
17609     resolveRegion.extent.depth = 1;
17610     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17611     EndCommandBuffer();
17612
17613     m_errorMonitor->VerifyFound();
17614
17615     vkDestroyImage(m_device->device(), srcImage, NULL);
17616     vkDestroyImage(m_device->device(), dstImage, NULL);
17617     vkFreeMemory(m_device->device(), srcMem, NULL);
17618     vkFreeMemory(m_device->device(), destMem, NULL);
17619 }
17620
17621 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
17622     // Create a single Image descriptor and cause it to first hit an error due
17623     //  to using a DS format, then cause it to hit error due to COLOR_BIT not
17624     //  set in aspect
17625     // The image format check comes 2nd in validation so we trigger it first,
17626     //  then when we cause aspect fail next, bad format check will be preempted
17627     VkResult err;
17628
17629     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17630                                          "Combination depth/stencil image formats can have only the ");
17631
17632     ASSERT_NO_FATAL_FAILURE(InitState());
17633
17634     VkDescriptorPoolSize ds_type_count = {};
17635     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17636     ds_type_count.descriptorCount = 1;
17637
17638     VkDescriptorPoolCreateInfo ds_pool_ci = {};
17639     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
17640     ds_pool_ci.pNext = NULL;
17641     ds_pool_ci.maxSets = 1;
17642     ds_pool_ci.poolSizeCount = 1;
17643     ds_pool_ci.pPoolSizes = &ds_type_count;
17644
17645     VkDescriptorPool ds_pool;
17646     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
17647     ASSERT_VK_SUCCESS(err);
17648
17649     VkDescriptorSetLayoutBinding dsl_binding = {};
17650     dsl_binding.binding = 0;
17651     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17652     dsl_binding.descriptorCount = 1;
17653     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
17654     dsl_binding.pImmutableSamplers = NULL;
17655
17656     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
17657     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
17658     ds_layout_ci.pNext = NULL;
17659     ds_layout_ci.bindingCount = 1;
17660     ds_layout_ci.pBindings = &dsl_binding;
17661     VkDescriptorSetLayout ds_layout;
17662     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
17663     ASSERT_VK_SUCCESS(err);
17664
17665     VkDescriptorSet descriptorSet;
17666     VkDescriptorSetAllocateInfo alloc_info = {};
17667     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
17668     alloc_info.descriptorSetCount = 1;
17669     alloc_info.descriptorPool = ds_pool;
17670     alloc_info.pSetLayouts = &ds_layout;
17671     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
17672     ASSERT_VK_SUCCESS(err);
17673
17674     VkImage image_bad;
17675     VkImage image_good;
17676     // One bad format and one good format for Color attachment
17677     const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
17678     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
17679     const int32_t tex_width = 32;
17680     const int32_t tex_height = 32;
17681
17682     VkImageCreateInfo image_create_info = {};
17683     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17684     image_create_info.pNext = NULL;
17685     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17686     image_create_info.format = tex_format_bad;
17687     image_create_info.extent.width = tex_width;
17688     image_create_info.extent.height = tex_height;
17689     image_create_info.extent.depth = 1;
17690     image_create_info.mipLevels = 1;
17691     image_create_info.arrayLayers = 1;
17692     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17693     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17694     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17695     image_create_info.flags = 0;
17696
17697     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
17698     ASSERT_VK_SUCCESS(err);
17699     image_create_info.format = tex_format_good;
17700     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17701     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
17702     ASSERT_VK_SUCCESS(err);
17703
17704     VkImageViewCreateInfo image_view_create_info = {};
17705     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17706     image_view_create_info.image = image_bad;
17707     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
17708     image_view_create_info.format = tex_format_bad;
17709     image_view_create_info.subresourceRange.baseArrayLayer = 0;
17710     image_view_create_info.subresourceRange.baseMipLevel = 0;
17711     image_view_create_info.subresourceRange.layerCount = 1;
17712     image_view_create_info.subresourceRange.levelCount = 1;
17713     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17714
17715     VkImageView view;
17716     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
17717
17718     m_errorMonitor->VerifyFound();
17719
17720     vkDestroyImage(m_device->device(), image_bad, NULL);
17721     vkDestroyImage(m_device->device(), image_good, NULL);
17722     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
17723     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
17724 }
17725
17726 TEST_F(VkLayerTest, ClearImageErrors) {
17727     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and "
17728                      "ClearDepthStencilImage with a color image.");
17729
17730     ASSERT_NO_FATAL_FAILURE(InitState());
17731     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17732
17733     // Renderpass is started here so end it as Clear cmds can't be in renderpass
17734     BeginCommandBuffer();
17735     m_commandBuffer->EndRenderPass();
17736
17737     // Color image
17738     VkClearColorValue clear_color;
17739     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
17740     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
17741     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
17742     const int32_t img_width = 32;
17743     const int32_t img_height = 32;
17744     VkImageCreateInfo image_create_info = {};
17745     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17746     image_create_info.pNext = NULL;
17747     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17748     image_create_info.format = color_format;
17749     image_create_info.extent.width = img_width;
17750     image_create_info.extent.height = img_height;
17751     image_create_info.extent.depth = 1;
17752     image_create_info.mipLevels = 1;
17753     image_create_info.arrayLayers = 1;
17754     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17755     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17756     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
17757
17758     vk_testing::Image color_image;
17759     color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
17760
17761     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
17762
17763     // Depth/Stencil image
17764     VkClearDepthStencilValue clear_value = {0};
17765     reqs = 0; // don't need HOST_VISIBLE DS image
17766     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
17767     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
17768     ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17769     ds_image_create_info.extent.width = 64;
17770     ds_image_create_info.extent.height = 64;
17771     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17772     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17773
17774     vk_testing::Image ds_image;
17775     ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs);
17776
17777     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
17778
17779     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
17780
17781     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17782                          &color_range);
17783
17784     m_errorMonitor->VerifyFound();
17785
17786     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with "
17787                                                                         "image created without "
17788                                                                         "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
17789
17790     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17791                          &color_range);
17792
17793     m_errorMonitor->VerifyFound();
17794
17795     // Call CmdClearDepthStencilImage with color image
17796     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17797                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
17798
17799     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(),
17800                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range);
17801
17802     m_errorMonitor->VerifyFound();
17803 }
17804 #endif // IMAGE_TESTS
17805
17806 #if defined(ANDROID) && defined(VALIDATION_APK)
17807 static bool initialized = false;
17808 static bool active = false;
17809
17810 // Convert Intents to argv
17811 // Ported from Hologram sample, only difference is flexible key
17812 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
17813     std::vector<std::string> args;
17814     JavaVM &vm = *app.activity->vm;
17815     JNIEnv *p_env;
17816     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
17817         return args;
17818
17819     JNIEnv &env = *p_env;
17820     jobject activity = app.activity->clazz;
17821     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
17822     jobject intent = env.CallObjectMethod(activity, get_intent_method);
17823     jmethodID get_string_extra_method =
17824         env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
17825     jvalue get_string_extra_args;
17826     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
17827     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
17828
17829     std::string args_str;
17830     if (extra_str) {
17831         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
17832         args_str = extra_utf;
17833         env.ReleaseStringUTFChars(extra_str, extra_utf);
17834         env.DeleteLocalRef(extra_str);
17835     }
17836
17837     env.DeleteLocalRef(get_string_extra_args.l);
17838     env.DeleteLocalRef(intent);
17839     vm.DetachCurrentThread();
17840
17841     // split args_str
17842     std::stringstream ss(args_str);
17843     std::string arg;
17844     while (std::getline(ss, arg, ' ')) {
17845         if (!arg.empty())
17846             args.push_back(arg);
17847     }
17848
17849     return args;
17850 }
17851
17852 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
17853
17854 static void processCommand(struct android_app *app, int32_t cmd) {
17855     switch (cmd) {
17856     case APP_CMD_INIT_WINDOW: {
17857         if (app->window) {
17858             initialized = true;
17859         }
17860         break;
17861     }
17862     case APP_CMD_GAINED_FOCUS: {
17863         active = true;
17864         break;
17865     }
17866     case APP_CMD_LOST_FOCUS: {
17867         active = false;
17868         break;
17869     }
17870     }
17871 }
17872
17873 void android_main(struct android_app *app) {
17874     app_dummy();
17875
17876     const char *appTag = "VulkanLayerValidationTests";
17877
17878     int vulkanSupport = InitVulkan();
17879     if (vulkanSupport == 0) {
17880         __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
17881         return;
17882     }
17883
17884     app->onAppCmd = processCommand;
17885     app->onInputEvent = processInput;
17886
17887     while (1) {
17888         int events;
17889         struct android_poll_source *source;
17890         while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
17891             if (source) {
17892                 source->process(app, source);
17893             }
17894
17895             if (app->destroyRequested != 0) {
17896                 VkTestFramework::Finish();
17897                 return;
17898             }
17899         }
17900
17901         if (initialized && active) {
17902             // Use the following key to send arguments to gtest, i.e.
17903             // --es args "--gtest_filter=-VkLayerTest.foo"
17904             const char key[] = "args";
17905             std::vector<std::string> args = get_args(*app, key);
17906
17907             std::string filter = "";
17908             if (args.size() > 0) {
17909                 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
17910                 filter += args[0];
17911             } else {
17912                 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
17913             }
17914
17915             int argc = 2;
17916             char *argv[] = {(char *)"foo", (char *)filter.c_str()};
17917             __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
17918
17919             // Route output to files until we can override the gtest output
17920             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
17921             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
17922
17923             ::testing::InitGoogleTest(&argc, argv);
17924             VkTestFramework::InitArgs(&argc, argv);
17925             ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17926
17927             int result = RUN_ALL_TESTS();
17928
17929             if (result != 0) {
17930                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
17931             } else {
17932                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
17933             }
17934
17935             VkTestFramework::Finish();
17936
17937             fclose(stdout);
17938             fclose(stderr);
17939
17940             ANativeActivity_finish(app->activity);
17941
17942             return;
17943         }
17944     }
17945 }
17946 #endif
17947
17948 int main(int argc, char **argv) {
17949     int result;
17950
17951 #ifdef ANDROID
17952     int vulkanSupport = InitVulkan();
17953     if (vulkanSupport == 0)
17954         return 1;
17955 #endif
17956
17957     ::testing::InitGoogleTest(&argc, argv);
17958     VkTestFramework::InitArgs(&argc, argv);
17959
17960     ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17961
17962     result = RUN_ALL_TESTS();
17963
17964     VkTestFramework::Finish();
17965     return result;
17966 }