Suppress all build warnings
[platform/upstream/Vulkan-LoaderAndValidationLayers.git] / tests / layer_validation_tests.cpp
1 /*
2  * Copyright (c) 2015-2016 The Khronos Group Inc.
3  * Copyright (c) 2015-2016 Valve Corporation
4  * Copyright (c) 2015-2016 LunarG, Inc.
5  * Copyright (c) 2015-2016 Google, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Author: Chia-I Wu <olvaffe@gmail.com>
14  * Author: Chris Forbes <chrisf@ijw.co.nz>
15  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16  * Author: Mark Lobodzinski <mark@lunarg.com>
17  * Author: Mike Stroyan <mike@LunarG.com>
18  * Author: Tobin Ehlis <tobine@google.com>
19  * Author: Tony Barbour <tony@LunarG.com>
20  * Author: Cody Northrop <cnorthrop@google.com>
21  */
22
23 #ifdef ANDROID
24 #include "vulkan_wrapper.h"
25 #else
26 #include <vulkan/vulkan.h>
27 #endif
28
29 #if defined(ANDROID) && defined(VALIDATION_APK)
30 #include <android/log.h>
31 #include <android_native_app_glue.h>
32 #endif
33
34 #include "icd-spv.h"
35 #include "test_common.h"
36 #include "vk_layer_config.h"
37 #include "vkrenderframework.h"
38 #include <unordered_set>
39
40 #define GLM_FORCE_RADIANS
41 #include "glm/glm.hpp"
42 #include <glm/gtc/matrix_transform.hpp>
43
44 #define PARAMETER_VALIDATION_TESTS 1
45 #define MEM_TRACKER_TESTS 1
46 #define OBJ_TRACKER_TESTS 1
47 #define DRAW_STATE_TESTS 1
48 #define THREADING_TESTS 1
49 #define SHADER_CHECKER_TESTS 1
50 #define DEVICE_LIMITS_TESTS 1
51 #define IMAGE_TESTS 1
52
53 //--------------------------------------------------------------------------------------
54 // Mesh and VertexFormat Data
55 //--------------------------------------------------------------------------------------
56 struct Vertex {
57     float posX, posY, posZ, posW; // Position data
58     float r, g, b, a;             // Color
59 };
60
61 #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
62
63 typedef enum _BsoFailSelect {
64     BsoFailNone = 0x00000000,
65     BsoFailLineWidth = 0x00000001,
66     BsoFailDepthBias = 0x00000002,
67     BsoFailViewport = 0x00000004,
68     BsoFailScissor = 0x00000008,
69     BsoFailBlend = 0x00000010,
70     BsoFailDepthBounds = 0x00000020,
71     BsoFailStencilReadMask = 0x00000040,
72     BsoFailStencilWriteMask = 0x00000080,
73     BsoFailStencilReference = 0x00000100,
74     BsoFailCmdClearAttachments = 0x00000200,
75     BsoFailIndexBuffer = 0x00000400,
76 } BsoFailSelect;
77
78 struct vktriangle_vs_uniform {
79     // Must start with MVP
80     float mvp[4][4];
81     float position[3][4];
82     float color[3][4];
83 };
84
85 static const char bindStateVertShaderText[] = "#version 450\n"
86                                               "vec2 vertices[3];\n"
87                                               "out gl_PerVertex {\n"
88                                               "    vec4 gl_Position;\n"
89                                               "};\n"
90                                               "void main() {\n"
91                                               "      vertices[0] = vec2(-1.0, -1.0);\n"
92                                               "      vertices[1] = vec2( 1.0, -1.0);\n"
93                                               "      vertices[2] = vec2( 0.0,  1.0);\n"
94                                               "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
95                                               "}\n";
96
97 static const char bindStateFragShaderText[] = "#version 450\n"
98                                               "\n"
99                                               "layout(location = 0) out vec4 uFragColor;\n"
100                                               "void main(){\n"
101                                               "   uFragColor = vec4(0,1,0,1);\n"
102                                               "}\n";
103
104 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
105                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
106                                                 void *pUserData);
107
108 // ********************************************************
109 // ErrorMonitor Usage:
110 //
111 // Call SetDesiredFailureMsg with a string to be compared against all
112 // encountered log messages. Passing NULL will match all log messages.
113 // logMsg will return true for skipCall only if msg is matched or NULL.
114 //
115 // Call DesiredMsgFound to determine if the desired failure message
116 // was encountered.
117
118 class ErrorMonitor {
119   public:
120     ErrorMonitor() {
121         test_platform_thread_create_mutex(&m_mutex);
122         test_platform_thread_lock_mutex(&m_mutex);
123         m_msgFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT;
124         m_bailout = NULL;
125         m_desiredMsgSet = false;
126         test_platform_thread_unlock_mutex(&m_mutex);
127     }
128
129     ~ErrorMonitor() { test_platform_thread_delete_mutex(&m_mutex); }
130
131     void SetDesiredFailureMsg(VkFlags msgFlags, const char *msgString) {
132         // also discard all collected messages to this point
133         test_platform_thread_lock_mutex(&m_mutex);
134         m_failureMsgs.clear();
135         m_otherMsgs.clear();
136         m_desiredMsgs.insert(msgString);
137         m_msgFound = VK_FALSE;
138         m_msgFlags = msgFlags;
139         m_desiredMsgSet = true;
140         test_platform_thread_unlock_mutex(&m_mutex);
141     }
142
143     VkBool32 CheckForDesiredMsg(const char *msgString) {
144         VkBool32 result = VK_FALSE;
145         test_platform_thread_lock_mutex(&m_mutex);
146         if (m_bailout != NULL) {
147             *m_bailout = true;
148         }
149         string errorString(msgString);
150         bool found_expected = false;
151         for (auto desired_msg : m_desiredMsgs) {
152             if (errorString.find(desired_msg) != string::npos) {
153                 found_expected = true;
154                 m_failureMsgs.insert(errorString);
155                 m_msgFound = VK_TRUE;
156                 result = VK_TRUE;
157                 // We only want one match for each expected error so remove from set here
158                 // Since we're about the break the loop it's ok to remove from set we're iterating over
159                 m_desiredMsgs.erase(desired_msg);
160                 break;
161             }
162         }
163         if (!found_expected) {
164             printf("Unexpected: %s\n", msgString);
165             m_otherMsgs.push_back(errorString);
166         }
167         test_platform_thread_unlock_mutex(&m_mutex);
168         return result;
169     }
170
171     vector<string> GetOtherFailureMsgs(void) { return m_otherMsgs; }
172
173     VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; }
174
175     VkBool32 DesiredMsgFound(void) { return m_msgFound; }
176
177     void SetBailout(bool *bailout) { m_bailout = bailout; }
178
179     void DumpFailureMsgs(void) {
180         vector<string> otherMsgs = GetOtherFailureMsgs();
181         cout << "Other error messages logged for this test were:" << endl;
182         for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) {
183             cout << "     " << *iter << endl;
184         }
185     }
186
187     // Helpers
188
189     // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
190     void ExpectSuccess(VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
191         m_msgFlags = message_flag_mask;
192         // Match ANY message matching specified type
193         SetDesiredFailureMsg(message_flag_mask, "");
194     }
195
196     void VerifyFound() {
197         // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages.
198         if (!DesiredMsgFound()) {
199             DumpFailureMsgs();
200             for (auto desired_msg : m_desiredMsgs) {
201                 FAIL() << "Did not receive expected error '" << desired_msg << "'";
202             }
203         }
204     }
205
206     void VerifyNotFound() {
207         // ExpectSuccess() configured us to match anything. Any error is a failure.
208         if (DesiredMsgFound()) {
209             DumpFailureMsgs();
210             for (auto msg : m_failureMsgs) {
211                 FAIL() << "Expected to succeed but got error: " << msg;
212             }
213         }
214     }
215
216   private:
217     VkFlags m_msgFlags;
218     std::unordered_set<string> m_desiredMsgs;
219     std::unordered_set<string> m_failureMsgs;
220     vector<string> m_otherMsgs;
221     test_platform_thread_mutex m_mutex;
222     bool *m_bailout;
223     VkBool32 m_msgFound;
224     bool m_desiredMsgSet;
225 };
226
227 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
228                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
229                                                 void *pUserData) {
230     ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
231     if (msgFlags & errMonitor->GetMessageFlags()) {
232         return errMonitor->CheckForDesiredMsg(pMsg);
233     }
234     return false;
235 }
236
237 class VkLayerTest : public VkRenderFramework {
238   public:
239     VkResult BeginCommandBuffer(VkCommandBufferObj &commandBuffer);
240     VkResult EndCommandBuffer(VkCommandBufferObj &commandBuffer);
241     void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
242     void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet,
243                                 BsoFailSelect failMask);
244     void GenericDrawPreparation(VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) {
245         GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failMask);
246     }
247
248     /* Convenience functions that use built-in command buffer */
249     VkResult BeginCommandBuffer() { return BeginCommandBuffer(*m_commandBuffer); }
250     VkResult EndCommandBuffer() { return EndCommandBuffer(*m_commandBuffer); }
251     void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
252         m_commandBuffer->Draw(vertexCount, instanceCount, firstVertex, firstInstance);
253     }
254     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
255                      uint32_t firstInstance) {
256         m_commandBuffer->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
257     }
258     void QueueCommandBuffer(bool checkSuccess = true) { m_commandBuffer->QueueCommandBuffer(checkSuccess); }
259     void QueueCommandBuffer(const VkFence &fence) { m_commandBuffer->QueueCommandBuffer(fence); }
260     void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding) {
261         m_commandBuffer->BindVertexBuffer(vertexBuffer, offset, binding);
262     }
263     void BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset) {
264         m_commandBuffer->BindIndexBuffer(indexBuffer, offset);
265     }
266
267   protected:
268     ErrorMonitor *m_errorMonitor;
269     bool m_enableWSI;
270
271     virtual void SetUp() {
272         std::vector<const char *> instance_layer_names;
273         std::vector<const char *> instance_extension_names;
274         std::vector<const char *> device_extension_names;
275
276         instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
277         /*
278          * Since CreateDbgMsgCallback is an instance level extension call
279          * any extension / layer that utilizes that feature also needs
280          * to be enabled at create instance time.
281          */
282         // Use Threading layer first to protect others from
283         // ThreadCommandBufferCollision test
284         instance_layer_names.push_back("VK_LAYER_GOOGLE_threading");
285         instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
286         instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
287         instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
288         instance_layer_names.push_back("VK_LAYER_LUNARG_image");
289         instance_layer_names.push_back("VK_LAYER_LUNARG_swapchain");
290         instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
291
292         if (m_enableWSI) {
293             instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
294             device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
295 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
296 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
297             instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
298 #endif // VK_USE_PLATFORM_ANDROID_KHR
299 #if defined(VK_USE_PLATFORM_MIR_KHR)
300             instance_extension_names.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
301 #endif // VK_USE_PLATFORM_MIR_KHR
302 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
303             instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
304 #endif // VK_USE_PLATFORM_WAYLAND_KHR
305 #if defined(VK_USE_PLATFORM_WIN32_KHR)
306             instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
307 #endif // VK_USE_PLATFORM_WIN32_KHR
308 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
309 #if defined(VK_USE_PLATFORM_XCB_KHR)
310             instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
311 #elif defined(VK_USE_PLATFORM_XLIB_KHR)
312             instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
313 #endif // VK_USE_PLATFORM_XLIB_KHR
314         }
315
316         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
317         this->app_info.pNext = NULL;
318         this->app_info.pApplicationName = "layer_tests";
319         this->app_info.applicationVersion = 1;
320         this->app_info.pEngineName = "unittest";
321         this->app_info.engineVersion = 1;
322         this->app_info.apiVersion = VK_API_VERSION_1_0;
323
324         m_errorMonitor = new ErrorMonitor;
325         InitFramework(instance_layer_names, instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
326     }
327
328     virtual void TearDown() {
329         // Clean up resources before we reset
330         ShutdownFramework();
331         delete m_errorMonitor;
332     }
333
334     VkLayerTest() { m_enableWSI = false; }
335 };
336
337 VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &commandBuffer) {
338     VkResult result;
339
340     result = commandBuffer.BeginCommandBuffer();
341
342     /*
343      * For render test all drawing happens in a single render pass
344      * on a single command buffer.
345      */
346     if (VK_SUCCESS == result && renderPass()) {
347         commandBuffer.BeginRenderPass(renderPassBeginInfo());
348     }
349
350     return result;
351 }
352
353 VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &commandBuffer) {
354     VkResult result;
355
356     if (renderPass()) {
357         commandBuffer.EndRenderPass();
358     }
359
360     result = commandBuffer.EndCommandBuffer();
361
362     return result;
363 }
364
365 void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask) {
366     // Create identity matrix
367     int i;
368     struct vktriangle_vs_uniform data;
369
370     glm::mat4 Projection = glm::mat4(1.0f);
371     glm::mat4 View = glm::mat4(1.0f);
372     glm::mat4 Model = glm::mat4(1.0f);
373     glm::mat4 MVP = Projection * View * Model;
374     const int matrixSize = sizeof(MVP);
375     const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
376
377     memcpy(&data.mvp, &MVP[0][0], matrixSize);
378
379     static const Vertex tri_data[] = {
380         {XYZ1(-1, -1, 0), XYZ1(1.f, 0.f, 0.f)}, {XYZ1(1, -1, 0), XYZ1(0.f, 1.f, 0.f)}, {XYZ1(0, 1, 0), XYZ1(0.f, 0.f, 1.f)},
381     };
382
383     for (i = 0; i < 3; i++) {
384         data.position[i][0] = tri_data[i].posX;
385         data.position[i][1] = tri_data[i].posY;
386         data.position[i][2] = tri_data[i].posZ;
387         data.position[i][3] = tri_data[i].posW;
388         data.color[i][0] = tri_data[i].r;
389         data.color[i][1] = tri_data[i].g;
390         data.color[i][2] = tri_data[i].b;
391         data.color[i][3] = tri_data[i].a;
392     }
393
394     ASSERT_NO_FATAL_FAILURE(InitViewport());
395
396     VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data,
397                                        VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
398
399     VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
400     VkShaderObj ps(m_device, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
401
402     VkPipelineObj pipelineobj(m_device);
403     pipelineobj.AddColorAttachment();
404     pipelineobj.AddShader(&vs);
405     pipelineobj.AddShader(&ps);
406     if (failMask & BsoFailLineWidth) {
407         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH);
408         VkPipelineInputAssemblyStateCreateInfo ia_state = {};
409         ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
410         ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
411         pipelineobj.SetInputAssembly(&ia_state);
412     }
413     if (failMask & BsoFailDepthBias) {
414         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS);
415         VkPipelineRasterizationStateCreateInfo rs_state = {};
416         rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
417         rs_state.depthBiasEnable = VK_TRUE;
418         rs_state.lineWidth = 1.0f;
419         pipelineobj.SetRasterization(&rs_state);
420     }
421     // Viewport and scissors must stay in synch or other errors will occur than
422     // the ones we want
423     if (failMask & BsoFailViewport) {
424         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
425     }
426     if (failMask & BsoFailScissor) {
427         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
428     }
429     if (failMask & BsoFailBlend) {
430         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
431         VkPipelineColorBlendAttachmentState att_state = {};
432         att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
433         att_state.blendEnable = VK_TRUE;
434         pipelineobj.AddColorAttachment(0, &att_state);
435     }
436     if (failMask & BsoFailDepthBounds) {
437         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
438     }
439     if (failMask & BsoFailStencilReadMask) {
440         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
441     }
442     if (failMask & BsoFailStencilWriteMask) {
443         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
444     }
445     if (failMask & BsoFailStencilReference) {
446         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
447     }
448
449     VkDescriptorSetObj descriptorSet(m_device);
450     descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
451
452     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
453     ASSERT_VK_SUCCESS(BeginCommandBuffer());
454
455     GenericDrawPreparation(pipelineobj, descriptorSet, failMask);
456
457     // render triangle
458     if (failMask & BsoFailIndexBuffer) {
459         // Use DrawIndexed w/o an index buffer bound
460         DrawIndexed(3, 1, 0, 0, 0);
461     } else {
462         Draw(3, 1, 0, 0);
463     }
464
465     if (failMask & BsoFailCmdClearAttachments) {
466         VkClearAttachment color_attachment = {};
467         color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
468         color_attachment.colorAttachment = 1; // Someone who knew what they were doing would use 0 for the index;
469         VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0};
470
471         vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
472     }
473
474     // finalize recording of the command buffer
475     EndCommandBuffer();
476
477     QueueCommandBuffer();
478 }
479
480 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj,
481                                          VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) {
482     if (m_depthStencil->Initialized()) {
483         commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
484     } else {
485         commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
486     }
487
488     commandBuffer->PrepareAttachments();
489     // Make sure depthWriteEnable is set so that Depth fail test will work
490     // correctly
491     // Make sure stencilTestEnable is set so that Stencil fail test will work
492     // correctly
493     VkStencilOpState stencil = {};
494     stencil.failOp = VK_STENCIL_OP_KEEP;
495     stencil.passOp = VK_STENCIL_OP_KEEP;
496     stencil.depthFailOp = VK_STENCIL_OP_KEEP;
497     stencil.compareOp = VK_COMPARE_OP_NEVER;
498
499     VkPipelineDepthStencilStateCreateInfo ds_ci = {};
500     ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
501     ds_ci.pNext = NULL;
502     ds_ci.depthTestEnable = VK_FALSE;
503     ds_ci.depthWriteEnable = VK_TRUE;
504     ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
505     ds_ci.depthBoundsTestEnable = VK_FALSE;
506     if (failMask & BsoFailDepthBounds) {
507         ds_ci.depthBoundsTestEnable = VK_TRUE;
508         ds_ci.maxDepthBounds = 0.0f;
509         ds_ci.minDepthBounds = 0.0f;
510     }
511     ds_ci.stencilTestEnable = VK_TRUE;
512     ds_ci.front = stencil;
513     ds_ci.back = stencil;
514
515     pipelineobj.SetDepthStencil(&ds_ci);
516     pipelineobj.SetViewport(m_viewports);
517     pipelineobj.SetScissor(m_scissors);
518     descriptorSet.CreateVKDescriptorSet(commandBuffer);
519     VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
520     ASSERT_VK_SUCCESS(err);
521     commandBuffer->BindPipeline(pipelineobj);
522     commandBuffer->BindDescriptorSet(descriptorSet);
523 }
524
525 class VkWsiEnabledLayerTest : public VkLayerTest {
526   public:
527   protected:
528     VkWsiEnabledLayerTest() { m_enableWSI = true; }
529 };
530
531 class VkBufferTest {
532   public:
533     enum eTestEnFlags {
534         eDoubleDelete,
535         eInvalidDeviceOffset,
536         eInvalidMemoryOffset,
537         eBindNullBuffer,
538         eFreeInvalidHandle,
539         eNone,
540     };
541
542     enum eTestConditions { eOffsetAlignment = 1 };
543
544     static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) {
545         if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) {
546             return true;
547         }
548         VkDeviceSize offset_limit = 0;
549         if (eInvalidMemoryOffset == aTestFlag) {
550             VkBuffer vulkanBuffer;
551             VkBufferCreateInfo buffer_create_info = {};
552             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
553             buffer_create_info.size = 32;
554             buffer_create_info.usage = aBufferUsage;
555
556             vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer);
557             VkMemoryRequirements memory_reqs = {};
558
559             vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs);
560             vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr);
561             offset_limit = memory_reqs.alignment;
562         } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) {
563             offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment;
564         } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) {
565             offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment;
566         } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) {
567             offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment;
568         }
569         if (eOffsetAlignment < offset_limit) {
570             return true;
571         }
572         return false;
573     }
574
575     // A constructor which performs validation tests within construction.
576     VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone)
577         : AllocateCurrent(false), BoundCurrent(false), CreateCurrent(false), VulkanDevice(aVulkanDevice->device()) {
578
579         if (eBindNullBuffer == aTestFlag) {
580             VulkanMemory = 0;
581             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
582         } else {
583             VkBufferCreateInfo buffer_create_info = {};
584             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
585             buffer_create_info.size = 32;
586             buffer_create_info.usage = aBufferUsage;
587
588             vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer);
589
590             CreateCurrent = true;
591
592             VkMemoryRequirements memory_requirements;
593             vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements);
594
595             VkMemoryAllocateInfo memory_allocate_info = {};
596             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
597             memory_allocate_info.allocationSize = memory_requirements.size;
598             bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info,
599                                                              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
600             if (!pass) {
601                 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
602                 return;
603             }
604
605             vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory);
606             AllocateCurrent = true;
607             // NB: 1 is intentionally an invalid offset value
608             const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag;
609             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0);
610             BoundCurrent = true;
611
612             InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
613         }
614     }
615
616     ~VkBufferTest() {
617         if (CreateCurrent) {
618             vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
619         }
620         if (AllocateCurrent) {
621             if (InvalidDeleteEn) {
622                 union {
623                     VkDeviceMemory device_memory;
624                     unsigned long long index_access;
625                 } bad_index;
626
627                 bad_index.device_memory = VulkanMemory;
628                 bad_index.index_access++;
629
630                 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr);
631             }
632             vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
633         }
634     }
635
636     bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; }
637
638     const VkBuffer &GetBuffer() { return VulkanBuffer; }
639
640     void TestDoubleDestroy() {
641         // Destroy the buffer but leave the flag set, which will cause
642         // the buffer to be destroyed again in the destructor.
643         vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
644     }
645
646   protected:
647     bool AllocateCurrent;
648     bool BoundCurrent;
649     bool CreateCurrent;
650     bool InvalidDeleteEn;
651
652     VkBuffer VulkanBuffer;
653     VkDevice VulkanDevice;
654     VkDeviceMemory VulkanMemory;
655 };
656
657 class VkVerticesObj {
658   public:
659     VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride,
660                   VkDeviceSize aVertexCount, const float *aVerticies)
661         : BoundCurrent(false), AttributeCount(aAttributeCount), BindingCount(aBindingCount), BindId(BindIdGenerator),
662           PipelineVertexInputStateCreateInfo(),
663           VulkanMemoryBuffer(aVulkanDevice, 1, static_cast<int>(aByteStride * aVertexCount),
664                              reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) {
665         BindIdGenerator++; // NB: This can wrap w/misuse
666
667         VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount];
668         VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount];
669
670         PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription;
671         PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount;
672         PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription;
673         PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount;
674         PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
675
676         unsigned i = 0;
677         do {
678             VertexInputAttributeDescription[i].binding = BindId;
679             VertexInputAttributeDescription[i].location = i;
680             VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT;
681             VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride;
682             i++;
683         } while (AttributeCount < i);
684
685         i = 0;
686         do {
687             VertexInputBindingDescription[i].binding = BindId;
688             VertexInputBindingDescription[i].stride = aByteStride;
689             VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
690             i++;
691         } while (BindingCount < i);
692     }
693
694     ~VkVerticesObj() {
695         if (VertexInputAttributeDescription) {
696             delete[] VertexInputAttributeDescription;
697         }
698         if (VertexInputBindingDescription) {
699             delete[] VertexInputBindingDescription;
700         }
701     }
702
703     bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
704         aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount);
705         aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount);
706         return true;
707     }
708
709     void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) {
710         VkDeviceSize *offsetList;
711         unsigned offsetCount;
712
713         if (aOffsetCount) {
714             offsetList = aOffsetList;
715             offsetCount = aOffsetCount;
716         } else {
717             offsetList = new VkDeviceSize[1]();
718             offsetCount = 1;
719         }
720
721         vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList);
722         BoundCurrent = true;
723
724         if (!aOffsetCount) {
725             delete[] offsetList;
726         }
727     }
728
729   protected:
730     static uint32_t BindIdGenerator;
731
732     bool BoundCurrent;
733     unsigned AttributeCount;
734     unsigned BindingCount;
735     uint32_t BindId;
736
737     VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
738     VkVertexInputAttributeDescription *VertexInputAttributeDescription;
739     VkVertexInputBindingDescription *VertexInputBindingDescription;
740     VkConstantBufferObj VulkanMemoryBuffer;
741 };
742
743 uint32_t VkVerticesObj::BindIdGenerator;
744 // ********************************************************************************************************************
745 // ********************************************************************************************************************
746 // ********************************************************************************************************************
747 // ********************************************************************************************************************
748 #if PARAMETER_VALIDATION_TESTS
749 TEST_F(VkLayerTest, RequiredParameter) {
750     TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, "
751                      "pointer, array, and array count parameters");
752
753     ASSERT_NO_FATAL_FAILURE(InitState());
754
755     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL");
756     // Specify NULL for a pointer to a handle
757     // Expected to trigger an error with
758     // parameter_validation::validate_required_pointer
759     vkGetPhysicalDeviceFeatures(gpu(), NULL);
760     m_errorMonitor->VerifyFound();
761
762     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
763                                          "required parameter pQueueFamilyPropertyCount specified as NULL");
764     // Specify NULL for pointer to array count
765     // Expected to trigger an error with parameter_validation::validate_array
766     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
767     m_errorMonitor->VerifyFound();
768
769     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter viewportCount must be greater than 0");
770     // Specify 0 for a required array count
771     // Expected to trigger an error with parameter_validation::validate_array
772     VkViewport view_port = {};
773     m_commandBuffer->SetViewport(0, 0, &view_port);
774     m_errorMonitor->VerifyFound();
775
776     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pViewports specified as NULL");
777     // Specify NULL for a required array
778     // Expected to trigger an error with parameter_validation::validate_array
779     m_commandBuffer->SetViewport(0, 1, NULL);
780     m_errorMonitor->VerifyFound();
781
782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE");
783     // Specify VK_NULL_HANDLE for a required handle
784     // Expected to trigger an error with
785     // parameter_validation::validate_required_handle
786     vkUnmapMemory(device(), VK_NULL_HANDLE);
787     m_errorMonitor->VerifyFound();
788
789     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
790                                          "required parameter pFences[0] specified as VK_NULL_HANDLE");
791     // Specify VK_NULL_HANDLE for a required handle array entry
792     // Expected to trigger an error with
793     // parameter_validation::validate_required_handle_array
794     VkFence fence = VK_NULL_HANDLE;
795     vkResetFences(device(), 1, &fence);
796     m_errorMonitor->VerifyFound();
797
798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL");
799     // Specify NULL for a required struct pointer
800     // Expected to trigger an error with
801     // parameter_validation::validate_struct_type
802     VkDeviceMemory memory = VK_NULL_HANDLE;
803     vkAllocateMemory(device(), NULL, NULL, &memory);
804     m_errorMonitor->VerifyFound();
805
806     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0");
807     // Specify 0 for a required VkFlags parameter
808     // Expected to trigger an error with parameter_validation::validate_flags
809     m_commandBuffer->SetStencilReference(0, 0);
810     m_errorMonitor->VerifyFound();
811
812     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
813     // Specify 0 for a required VkFlags array entry
814     // Expected to trigger an error with
815     // parameter_validation::validate_flags_array
816     VkSemaphore semaphore = VK_NULL_HANDLE;
817     VkPipelineStageFlags stageFlags = 0;
818     VkSubmitInfo submitInfo = {};
819     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
820     submitInfo.waitSemaphoreCount = 1;
821     submitInfo.pWaitSemaphores = &semaphore;
822     submitInfo.pWaitDstStageMask = &stageFlags;
823     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
824     m_errorMonitor->VerifyFound();
825 }
826
827 TEST_F(VkLayerTest, ReservedParameter) {
828     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
829
830     ASSERT_NO_FATAL_FAILURE(InitState());
831
832     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0");
833     // Specify 0 for a reserved VkFlags parameter
834     // Expected to trigger an error with
835     // parameter_validation::validate_reserved_flags
836     VkEvent event_handle = VK_NULL_HANDLE;
837     VkEventCreateInfo event_info = {};
838     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
839     event_info.flags = 1;
840     vkCreateEvent(device(), &event_info, NULL, &event_handle);
841     m_errorMonitor->VerifyFound();
842 }
843
844 TEST_F(VkLayerTest, InvalidStructSType) {
845     TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan "
846                      "structure's sType field");
847
848     ASSERT_NO_FATAL_FAILURE(InitState());
849
850     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be");
851     // Zero struct memory, effectively setting sType to
852     // VK_STRUCTURE_TYPE_APPLICATION_INFO
853     // Expected to trigger an error with
854     // parameter_validation::validate_struct_type
855     VkMemoryAllocateInfo alloc_info = {};
856     VkDeviceMemory memory = VK_NULL_HANDLE;
857     vkAllocateMemory(device(), &alloc_info, NULL, &memory);
858     m_errorMonitor->VerifyFound();
859
860     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be");
861     // Zero struct memory, effectively setting sType to
862     // VK_STRUCTURE_TYPE_APPLICATION_INFO
863     // Expected to trigger an error with
864     // parameter_validation::validate_struct_type_array
865     VkSubmitInfo submit_info = {};
866     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
867     m_errorMonitor->VerifyFound();
868 }
869
870 TEST_F(VkLayerTest, InvalidStructPNext) {
871     TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
872
873     ASSERT_NO_FATAL_FAILURE(InitState());
874
875     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
876     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be
877     // NULL.
878     // Need to pick a function that has no allowed pNext structure types.
879     // Expected to trigger an error with
880     // parameter_validation::validate_struct_pnext
881     VkEvent event = VK_NULL_HANDLE;
882     VkEventCreateInfo event_alloc_info = {};
883     // Zero-initialization will provide the correct sType
884     VkApplicationInfo app_info = {};
885     event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
886     event_alloc_info.pNext = &app_info;
887     vkCreateEvent(device(), &event_alloc_info, NULL, &event);
888     m_errorMonitor->VerifyFound();
889
890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
891                                          " chain includes a structure with unexpected VkStructureType ");
892     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
893     // a function that has allowed pNext structure types and specify
894     // a structure type that is not allowed.
895     // Expected to trigger an error with
896     // parameter_validation::validate_struct_pnext
897     VkDeviceMemory memory = VK_NULL_HANDLE;
898     VkMemoryAllocateInfo memory_alloc_info = {};
899     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
900     memory_alloc_info.pNext = &app_info;
901     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
902     m_errorMonitor->VerifyFound();
903
904     // Positive test to check parameter_validation and unique_objects support
905     // for NV_dedicated_allocation
906     uint32_t extension_count = 0;
907     bool supports_nv_dedicated_allocation = false;
908     VkResult err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, nullptr);
909     ASSERT_VK_SUCCESS(err);
910
911     if (extension_count > 0) {
912         std::vector<VkExtensionProperties> available_extensions(extension_count);
913
914         err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]);
915         ASSERT_VK_SUCCESS(err);
916
917         for (const auto &extension_props : available_extensions) {
918             if (strcmp(extension_props.extensionName, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
919                 supports_nv_dedicated_allocation = true;
920             }
921         }
922     }
923
924     if (supports_nv_dedicated_allocation) {
925         m_errorMonitor->ExpectSuccess();
926
927         VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
928         dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
929         dedicated_buffer_create_info.pNext = nullptr;
930         dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
931
932         uint32_t queue_family_index = 0;
933         VkBufferCreateInfo buffer_create_info = {};
934         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
935         buffer_create_info.pNext = &dedicated_buffer_create_info;
936         buffer_create_info.size = 1024;
937         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
938         buffer_create_info.queueFamilyIndexCount = 1;
939         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
940
941         VkBuffer buffer;
942         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
943         ASSERT_VK_SUCCESS(err);
944
945         VkMemoryRequirements memory_reqs;
946         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
947
948         VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
949         dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
950         dedicated_memory_info.pNext = nullptr;
951         dedicated_memory_info.buffer = buffer;
952         dedicated_memory_info.image = VK_NULL_HANDLE;
953
954         VkMemoryAllocateInfo memory_info = {};
955         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
956         memory_info.pNext = &dedicated_memory_info;
957         memory_info.allocationSize = memory_reqs.size;
958
959         bool pass;
960         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
961         ASSERT_TRUE(pass);
962
963         VkDeviceMemory buffer_memory;
964         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
965         ASSERT_VK_SUCCESS(err);
966
967         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
968         ASSERT_VK_SUCCESS(err);
969
970         vkDestroyBuffer(m_device->device(), buffer, NULL);
971         vkFreeMemory(m_device->device(), buffer_memory, NULL);
972
973         m_errorMonitor->VerifyNotFound();
974     }
975 }
976
977 TEST_F(VkLayerTest, UnrecognizedValue) {
978     TEST_DESCRIPTION("Specify unrecognized Vulkan enumeration, flags, and VkBool32 values");
979
980     ASSERT_NO_FATAL_FAILURE(InitState());
981
982     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end "
983                                                                         "range of the core VkFormat "
984                                                                         "enumeration tokens");
985     // Specify an invalid VkFormat value
986     // Expected to trigger an error with
987     // parameter_validation::validate_ranged_enum
988     VkFormatProperties format_properties;
989     vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
990     m_errorMonitor->VerifyFound();
991
992     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
993     // Specify an invalid VkFlags bitmask value
994     // Expected to trigger an error with parameter_validation::validate_flags
995     VkImageFormatProperties image_format_properties;
996     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
997                                              static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
998     m_errorMonitor->VerifyFound();
999
1000     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
1001     // Specify an invalid VkFlags array entry
1002     // Expected to trigger an error with
1003     // parameter_validation::validate_flags_array
1004     VkSemaphore semaphore = VK_NULL_HANDLE;
1005     VkPipelineStageFlags stage_flags = static_cast<VkPipelineStageFlags>(1 << 25);
1006     VkSubmitInfo submit_info = {};
1007     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1008     submit_info.waitSemaphoreCount = 1;
1009     submit_info.pWaitSemaphores = &semaphore;
1010     submit_info.pWaitDstStageMask = &stage_flags;
1011     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1012     m_errorMonitor->VerifyFound();
1013
1014     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
1015     // Specify an invalid VkBool32 value
1016     // Expected to trigger a warning with
1017     // parameter_validation::validate_bool32
1018     VkSampler sampler = VK_NULL_HANDLE;
1019     VkSamplerCreateInfo sampler_info = {};
1020     sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1021     sampler_info.pNext = NULL;
1022     sampler_info.magFilter = VK_FILTER_NEAREST;
1023     sampler_info.minFilter = VK_FILTER_NEAREST;
1024     sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
1025     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1026     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1027     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1028     sampler_info.mipLodBias = 1.0;
1029     sampler_info.maxAnisotropy = 1;
1030     sampler_info.compareEnable = VK_FALSE;
1031     sampler_info.compareOp = VK_COMPARE_OP_NEVER;
1032     sampler_info.minLod = 1.0;
1033     sampler_info.maxLod = 1.0;
1034     sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
1035     sampler_info.unnormalizedCoordinates = VK_FALSE;
1036     // Not VK_TRUE or VK_FALSE
1037     sampler_info.anisotropyEnable = 3;
1038     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
1039     m_errorMonitor->VerifyFound();
1040 }
1041
1042 TEST_F(VkLayerTest, FailedReturnValue) {
1043     TEST_DESCRIPTION("Check for a message describing a VkResult failure code");
1044
1045     ASSERT_NO_FATAL_FAILURE(InitState());
1046
1047     // Find an unsupported image format
1048     VkFormat unsupported = VK_FORMAT_UNDEFINED;
1049     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
1050         VkFormat format = static_cast<VkFormat>(f);
1051         VkFormatProperties fProps = m_device->format_properties(format);
1052         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
1053             unsupported = format;
1054             break;
1055         }
1056     }
1057
1058     if (unsupported != VK_FORMAT_UNDEFINED) {
1059         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
1060                                              "the requested format is not supported on this device");
1061         // Specify an unsupported VkFormat value to generate a
1062         // VK_ERROR_FORMAT_NOT_SUPPORTED return code
1063         // Expected to trigger a warning from
1064         // parameter_validation::validate_result
1065         VkImageFormatProperties image_format_properties;
1066         VkResult err = vkGetPhysicalDeviceImageFormatProperties(gpu(), unsupported, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
1067                                                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &image_format_properties);
1068         ASSERT_TRUE(err == VK_ERROR_FORMAT_NOT_SUPPORTED);
1069         m_errorMonitor->VerifyFound();
1070     }
1071 }
1072
1073 TEST_F(VkLayerTest, UpdateBufferAlignment) {
1074     TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer");
1075     uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8};
1076
1077     ASSERT_NO_FATAL_FAILURE(InitState());
1078
1079     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1080     vk_testing::Buffer buffer;
1081     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1082
1083     BeginCommandBuffer();
1084     // Introduce failure by using dstOffset that is not multiple of 4
1085     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1086     m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
1087     m_errorMonitor->VerifyFound();
1088
1089     // Introduce failure by using dataSize that is not multiple of 4
1090     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1091     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
1092     m_errorMonitor->VerifyFound();
1093
1094     // Introduce failure by using dataSize that is < 0
1095     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1096                                          "must be greater than zero and less than or equal to 65536");
1097     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, -44, updateData);
1098     m_errorMonitor->VerifyFound();
1099
1100     // Introduce failure by using dataSize that is > 65536
1101     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1102                                          "must be greater than zero and less than or equal to 65536");
1103     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 80000, updateData);
1104     m_errorMonitor->VerifyFound();
1105
1106     EndCommandBuffer();
1107 }
1108
1109 TEST_F(VkLayerTest, FillBufferAlignment) {
1110     TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
1111
1112     ASSERT_NO_FATAL_FAILURE(InitState());
1113
1114     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1115     vk_testing::Buffer buffer;
1116     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1117
1118     BeginCommandBuffer();
1119
1120     // Introduce failure by using dstOffset that is not multiple of 4
1121     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1122     m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
1123     m_errorMonitor->VerifyFound();
1124
1125     // Introduce failure by using size that is not multiple of 4
1126     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
1127     m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
1128     m_errorMonitor->VerifyFound();
1129
1130     // Introduce failure by using size that is zero
1131     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero");
1132     m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111);
1133     m_errorMonitor->VerifyFound();
1134
1135     EndCommandBuffer();
1136 }
1137
1138 // This is a positive test. No failures are expected.
1139 TEST_F(VkLayerTest, IgnoreUnrelatedDescriptor) {
1140     TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSet validation code "
1141                      "is ignoring VkWriteDescriptorSet members that are not "
1142                      "related to the descriptor type specified by "
1143                      "VkWriteDescriptorSet::descriptorType.  Correct "
1144                      "validation behavior will result in the test running to "
1145                      "completion without validation errors.");
1146
1147     const uintptr_t invalid_ptr = 0xcdcdcdcd;
1148
1149     ASSERT_NO_FATAL_FAILURE(InitState());
1150
1151     // Image Case
1152     {
1153         m_errorMonitor->ExpectSuccess();
1154
1155         VkImage image;
1156         const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
1157         const int32_t tex_width = 32;
1158         const int32_t tex_height = 32;
1159         VkImageCreateInfo image_create_info = {};
1160         image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1161         image_create_info.pNext = NULL;
1162         image_create_info.imageType = VK_IMAGE_TYPE_2D;
1163         image_create_info.format = tex_format;
1164         image_create_info.extent.width = tex_width;
1165         image_create_info.extent.height = tex_height;
1166         image_create_info.extent.depth = 1;
1167         image_create_info.mipLevels = 1;
1168         image_create_info.arrayLayers = 1;
1169         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1170         image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1171         image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
1172         image_create_info.flags = 0;
1173         VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1174         ASSERT_VK_SUCCESS(err);
1175
1176         VkMemoryRequirements memory_reqs;
1177         VkDeviceMemory image_memory;
1178         bool pass;
1179         VkMemoryAllocateInfo memory_info = {};
1180         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1181         memory_info.pNext = NULL;
1182         memory_info.allocationSize = 0;
1183         memory_info.memoryTypeIndex = 0;
1184         vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
1185         memory_info.allocationSize = memory_reqs.size;
1186         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1187         ASSERT_TRUE(pass);
1188         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
1189         ASSERT_VK_SUCCESS(err);
1190         err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
1191         ASSERT_VK_SUCCESS(err);
1192
1193         VkImageViewCreateInfo image_view_create_info = {};
1194         image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1195         image_view_create_info.image = image;
1196         image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
1197         image_view_create_info.format = tex_format;
1198         image_view_create_info.subresourceRange.layerCount = 1;
1199         image_view_create_info.subresourceRange.baseMipLevel = 0;
1200         image_view_create_info.subresourceRange.levelCount = 1;
1201         image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1202
1203         VkImageView view;
1204         err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
1205         ASSERT_VK_SUCCESS(err);
1206
1207         VkDescriptorPoolSize ds_type_count = {};
1208         ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1209         ds_type_count.descriptorCount = 1;
1210
1211         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1212         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1213         ds_pool_ci.pNext = NULL;
1214         ds_pool_ci.maxSets = 1;
1215         ds_pool_ci.poolSizeCount = 1;
1216         ds_pool_ci.pPoolSizes = &ds_type_count;
1217
1218         VkDescriptorPool ds_pool;
1219         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1220         ASSERT_VK_SUCCESS(err);
1221
1222         VkDescriptorSetLayoutBinding dsl_binding = {};
1223         dsl_binding.binding = 0;
1224         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1225         dsl_binding.descriptorCount = 1;
1226         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1227         dsl_binding.pImmutableSamplers = NULL;
1228
1229         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1230         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1231         ds_layout_ci.pNext = NULL;
1232         ds_layout_ci.bindingCount = 1;
1233         ds_layout_ci.pBindings = &dsl_binding;
1234         VkDescriptorSetLayout ds_layout;
1235         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1236         ASSERT_VK_SUCCESS(err);
1237
1238         VkDescriptorSet descriptor_set;
1239         VkDescriptorSetAllocateInfo alloc_info = {};
1240         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1241         alloc_info.descriptorSetCount = 1;
1242         alloc_info.descriptorPool = ds_pool;
1243         alloc_info.pSetLayouts = &ds_layout;
1244         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1245         ASSERT_VK_SUCCESS(err);
1246
1247         VkDescriptorImageInfo image_info = {};
1248         image_info.imageView = view;
1249         image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1250
1251         VkWriteDescriptorSet descriptor_write;
1252         memset(&descriptor_write, 0, sizeof(descriptor_write));
1253         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1254         descriptor_write.dstSet = descriptor_set;
1255         descriptor_write.dstBinding = 0;
1256         descriptor_write.descriptorCount = 1;
1257         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1258         descriptor_write.pImageInfo = &image_info;
1259
1260         // Set pBufferInfo and pTexelBufferView to invalid values, which should
1261         // be
1262         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
1263         // This will most likely produce a crash if the parameter_validation
1264         // layer
1265         // does not correctly ignore pBufferInfo.
1266         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
1267         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
1268
1269         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1270
1271         m_errorMonitor->VerifyNotFound();
1272
1273         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1274         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1275         vkDestroyImageView(m_device->device(), view, NULL);
1276         vkDestroyImage(m_device->device(), image, NULL);
1277         vkFreeMemory(m_device->device(), image_memory, NULL);
1278     }
1279
1280     // Buffer Case
1281     {
1282         m_errorMonitor->ExpectSuccess();
1283
1284         VkBuffer buffer;
1285         uint32_t queue_family_index = 0;
1286         VkBufferCreateInfo buffer_create_info = {};
1287         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1288         buffer_create_info.size = 1024;
1289         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1290         buffer_create_info.queueFamilyIndexCount = 1;
1291         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
1292
1293         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1294         ASSERT_VK_SUCCESS(err);
1295
1296         VkMemoryRequirements memory_reqs;
1297         VkDeviceMemory buffer_memory;
1298         bool pass;
1299         VkMemoryAllocateInfo memory_info = {};
1300         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1301         memory_info.pNext = NULL;
1302         memory_info.allocationSize = 0;
1303         memory_info.memoryTypeIndex = 0;
1304
1305         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
1306         memory_info.allocationSize = memory_reqs.size;
1307         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1308         ASSERT_TRUE(pass);
1309
1310         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
1311         ASSERT_VK_SUCCESS(err);
1312         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
1313         ASSERT_VK_SUCCESS(err);
1314
1315         VkDescriptorPoolSize ds_type_count = {};
1316         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1317         ds_type_count.descriptorCount = 1;
1318
1319         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1320         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1321         ds_pool_ci.pNext = NULL;
1322         ds_pool_ci.maxSets = 1;
1323         ds_pool_ci.poolSizeCount = 1;
1324         ds_pool_ci.pPoolSizes = &ds_type_count;
1325
1326         VkDescriptorPool ds_pool;
1327         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1328         ASSERT_VK_SUCCESS(err);
1329
1330         VkDescriptorSetLayoutBinding dsl_binding = {};
1331         dsl_binding.binding = 0;
1332         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1333         dsl_binding.descriptorCount = 1;
1334         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1335         dsl_binding.pImmutableSamplers = NULL;
1336
1337         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1338         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1339         ds_layout_ci.pNext = NULL;
1340         ds_layout_ci.bindingCount = 1;
1341         ds_layout_ci.pBindings = &dsl_binding;
1342         VkDescriptorSetLayout ds_layout;
1343         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1344         ASSERT_VK_SUCCESS(err);
1345
1346         VkDescriptorSet descriptor_set;
1347         VkDescriptorSetAllocateInfo alloc_info = {};
1348         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1349         alloc_info.descriptorSetCount = 1;
1350         alloc_info.descriptorPool = ds_pool;
1351         alloc_info.pSetLayouts = &ds_layout;
1352         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1353         ASSERT_VK_SUCCESS(err);
1354
1355         VkDescriptorBufferInfo buffer_info = {};
1356         buffer_info.buffer = buffer;
1357         buffer_info.offset = 0;
1358         buffer_info.range = 1024;
1359
1360         VkWriteDescriptorSet descriptor_write;
1361         memset(&descriptor_write, 0, sizeof(descriptor_write));
1362         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1363         descriptor_write.dstSet = descriptor_set;
1364         descriptor_write.dstBinding = 0;
1365         descriptor_write.descriptorCount = 1;
1366         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1367         descriptor_write.pBufferInfo = &buffer_info;
1368
1369         // Set pImageInfo and pTexelBufferView to invalid values, which should
1370         // be
1371         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
1372         // This will most likely produce a crash if the parameter_validation
1373         // layer
1374         // does not correctly ignore pImageInfo.
1375         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
1376         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
1377
1378         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1379
1380         m_errorMonitor->VerifyNotFound();
1381
1382         vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
1383         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1384         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1385         vkDestroyBuffer(m_device->device(), buffer, NULL);
1386         vkFreeMemory(m_device->device(), buffer_memory, NULL);
1387     }
1388
1389     // Texel Buffer Case
1390     {
1391         m_errorMonitor->ExpectSuccess();
1392
1393         VkBuffer buffer;
1394         uint32_t queue_family_index = 0;
1395         VkBufferCreateInfo buffer_create_info = {};
1396         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1397         buffer_create_info.size = 1024;
1398         buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
1399         buffer_create_info.queueFamilyIndexCount = 1;
1400         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
1401
1402         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1403         ASSERT_VK_SUCCESS(err);
1404
1405         VkMemoryRequirements memory_reqs;
1406         VkDeviceMemory buffer_memory;
1407         bool pass;
1408         VkMemoryAllocateInfo memory_info = {};
1409         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1410         memory_info.pNext = NULL;
1411         memory_info.allocationSize = 0;
1412         memory_info.memoryTypeIndex = 0;
1413
1414         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
1415         memory_info.allocationSize = memory_reqs.size;
1416         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
1417         ASSERT_TRUE(pass);
1418
1419         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
1420         ASSERT_VK_SUCCESS(err);
1421         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
1422         ASSERT_VK_SUCCESS(err);
1423
1424         VkBufferViewCreateInfo buff_view_ci = {};
1425         buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
1426         buff_view_ci.buffer = buffer;
1427         buff_view_ci.format = VK_FORMAT_R8_UNORM;
1428         buff_view_ci.range = VK_WHOLE_SIZE;
1429         VkBufferView buffer_view;
1430         err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
1431
1432         VkDescriptorPoolSize ds_type_count = {};
1433         ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1434         ds_type_count.descriptorCount = 1;
1435
1436         VkDescriptorPoolCreateInfo ds_pool_ci = {};
1437         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1438         ds_pool_ci.pNext = NULL;
1439         ds_pool_ci.maxSets = 1;
1440         ds_pool_ci.poolSizeCount = 1;
1441         ds_pool_ci.pPoolSizes = &ds_type_count;
1442
1443         VkDescriptorPool ds_pool;
1444         err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1445         ASSERT_VK_SUCCESS(err);
1446
1447         VkDescriptorSetLayoutBinding dsl_binding = {};
1448         dsl_binding.binding = 0;
1449         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1450         dsl_binding.descriptorCount = 1;
1451         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1452         dsl_binding.pImmutableSamplers = NULL;
1453
1454         VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1455         ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1456         ds_layout_ci.pNext = NULL;
1457         ds_layout_ci.bindingCount = 1;
1458         ds_layout_ci.pBindings = &dsl_binding;
1459         VkDescriptorSetLayout ds_layout;
1460         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
1461         ASSERT_VK_SUCCESS(err);
1462
1463         VkDescriptorSet descriptor_set;
1464         VkDescriptorSetAllocateInfo alloc_info = {};
1465         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1466         alloc_info.descriptorSetCount = 1;
1467         alloc_info.descriptorPool = ds_pool;
1468         alloc_info.pSetLayouts = &ds_layout;
1469         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
1470         ASSERT_VK_SUCCESS(err);
1471
1472         VkWriteDescriptorSet descriptor_write;
1473         memset(&descriptor_write, 0, sizeof(descriptor_write));
1474         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1475         descriptor_write.dstSet = descriptor_set;
1476         descriptor_write.dstBinding = 0;
1477         descriptor_write.descriptorCount = 1;
1478         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1479         descriptor_write.pTexelBufferView = &buffer_view;
1480
1481         // Set pImageInfo and pBufferInfo to invalid values, which should be
1482         //  ignored for descriptorType ==
1483         //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
1484         // This will most likely produce a crash if the parameter_validation
1485         // layer
1486         // does not correctly ignore pImageInfo and pBufferInfo.
1487         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
1488         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
1489
1490         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1491
1492         m_errorMonitor->VerifyNotFound();
1493
1494         vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
1495         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
1496         vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
1497         vkDestroyBufferView(m_device->device(), buffer_view, NULL);
1498         vkDestroyBuffer(m_device->device(), buffer, NULL);
1499         vkFreeMemory(m_device->device(), buffer_memory, NULL);
1500     }
1501 }
1502
1503 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
1504     VkResult err;
1505
1506     TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a "
1507                      "pipeline when this feature is not enabled.");
1508
1509     ASSERT_NO_FATAL_FAILURE(InitState());
1510     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1511
1512     std::vector<const char *> device_extension_names;
1513     auto features = m_device->phy().features();
1514     // Artificially disable support for non-solid fill modes
1515     features.fillModeNonSolid = false;
1516     // The sacrificial device object
1517     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
1518
1519     VkRenderpassObj render_pass(&test_device);
1520
1521     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
1522     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1523     pipeline_layout_ci.setLayoutCount = 0;
1524     pipeline_layout_ci.pSetLayouts = NULL;
1525
1526     VkPipelineLayout pipeline_layout;
1527     err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1528     ASSERT_VK_SUCCESS(err);
1529
1530     VkPipelineRasterizationStateCreateInfo rs_ci = {};
1531     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1532     rs_ci.pNext = nullptr;
1533     rs_ci.lineWidth = 1.0f;
1534     rs_ci.rasterizerDiscardEnable = true;
1535
1536     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1537     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1538
1539     // Set polygonMode to unsupported value POINT, should fail
1540     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1541                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
1542     {
1543         VkPipelineObj pipe(&test_device);
1544         pipe.AddShader(&vs);
1545         pipe.AddShader(&fs);
1546         pipe.AddColorAttachment();
1547         // Introduce failure by setting unsupported polygon mode
1548         rs_ci.polygonMode = VK_POLYGON_MODE_POINT;
1549         pipe.SetRasterization(&rs_ci);
1550         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1551     }
1552     m_errorMonitor->VerifyFound();
1553
1554     // Try again with polygonMode=LINE, should fail
1555     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1556                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
1557     {
1558         VkPipelineObj pipe(&test_device);
1559         pipe.AddShader(&vs);
1560         pipe.AddShader(&fs);
1561         pipe.AddColorAttachment();
1562         // Introduce failure by setting unsupported polygon mode
1563         rs_ci.polygonMode = VK_POLYGON_MODE_LINE;
1564         pipe.SetRasterization(&rs_ci);
1565         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1566     }
1567     m_errorMonitor->VerifyFound();
1568
1569     // Try again with polygonMode=FILL. No error is expected
1570     m_errorMonitor->ExpectSuccess();
1571     {
1572         VkPipelineObj pipe(&test_device);
1573         pipe.AddShader(&vs);
1574         pipe.AddShader(&fs);
1575         pipe.AddColorAttachment();
1576         // Set polygonMode to a good value
1577         rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
1578         pipe.SetRasterization(&rs_ci);
1579         pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
1580     }
1581     m_errorMonitor->VerifyNotFound();
1582
1583     vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL);
1584 }
1585
1586 #endif // PARAMETER_VALIDATION_TESTS
1587
1588 #if MEM_TRACKER_TESTS
1589 #if 0
1590 TEST_F(VkLayerTest, CallResetCommandBufferBeforeCompletion)
1591 {
1592     vk_testing::Fence testFence;
1593     VkFenceCreateInfo fenceInfo = {};
1594     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1595     fenceInfo.pNext = NULL;
1596     fenceInfo.flags = 0;
1597
1598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting CB");
1599
1600     ASSERT_NO_FATAL_FAILURE(InitState());
1601
1602     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1603     vk_testing::Buffer buffer;
1604     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1605
1606     BeginCommandBuffer();
1607     m_commandBuffer->FillBuffer(buffer.handle(), 0, 4, 0x11111111);
1608     EndCommandBuffer();
1609
1610     testFence.init(*m_device, fenceInfo);
1611
1612     // Bypass framework since it does the waits automatically
1613     VkResult err = VK_SUCCESS;
1614     VkSubmitInfo submit_info;
1615     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1616     submit_info.pNext = NULL;
1617     submit_info.waitSemaphoreCount = 0;
1618     submit_info.pWaitSemaphores = NULL;
1619     submit_info.pWaitDstStageMask = NULL;
1620     submit_info.commandBufferCount = 1;
1621     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1622     submit_info.signalSemaphoreCount = 0;
1623     submit_info.pSignalSemaphores = NULL;
1624
1625     err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1626     ASSERT_VK_SUCCESS( err );
1627
1628     // Introduce failure by calling begin again before checking fence
1629     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
1630
1631     m_errorMonitor->VerifyFound();
1632 }
1633
1634 TEST_F(VkLayerTest, CallBeginCommandBufferBeforeCompletion)
1635 {
1636     vk_testing::Fence testFence;
1637     VkFenceCreateInfo fenceInfo = {};
1638     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1639     fenceInfo.pNext = NULL;
1640     fenceInfo.flags = 0;
1641
1642     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active CB");
1643
1644     ASSERT_NO_FATAL_FAILURE(InitState());
1645     ASSERT_NO_FATAL_FAILURE(InitViewport());
1646     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1647
1648     BeginCommandBuffer();
1649     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
1650     EndCommandBuffer();
1651
1652     testFence.init(*m_device, fenceInfo);
1653
1654     // Bypass framework since it does the waits automatically
1655     VkResult err = VK_SUCCESS;
1656     VkSubmitInfo submit_info;
1657     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1658     submit_info.pNext = NULL;
1659     submit_info.waitSemaphoreCount = 0;
1660     submit_info.pWaitSemaphores = NULL;
1661     submit_info.pWaitDstStageMask = NULL;
1662     submit_info.commandBufferCount = 1;
1663     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1664     submit_info.signalSemaphoreCount = 0;
1665     submit_info.pSignalSemaphores = NULL;
1666
1667     err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1668     ASSERT_VK_SUCCESS( err );
1669
1670     VkCommandBufferInheritanceInfo hinfo = {};
1671     VkCommandBufferBeginInfo info = {};
1672     info.flags       = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1673     info.sType       = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1674     info.renderPass  = VK_NULL_HANDLE;
1675     info.subpass     = 0;
1676     info.framebuffer = VK_NULL_HANDLE;
1677     info.occlusionQueryEnable = VK_FALSE;
1678     info.queryFlags = 0;
1679     info.pipelineStatistics = 0;
1680
1681     // Introduce failure by calling BCB again before checking fence
1682     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
1683
1684     m_errorMonitor->VerifyFound();
1685 }
1686 #endif
1687
1688 // This is a positive test. No failures are expected.
1689 TEST_F(VkLayerTest, TestAliasedMemoryTracking) {
1690     VkResult err;
1691     bool pass;
1692
1693     TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
1694                      "the buffer, create an image, and bind the same memory to "
1695                      "it");
1696
1697     m_errorMonitor->ExpectSuccess();
1698
1699     ASSERT_NO_FATAL_FAILURE(InitState());
1700
1701     VkBuffer buffer;
1702     VkImage image;
1703     VkDeviceMemory mem;
1704     VkMemoryRequirements mem_reqs;
1705
1706     VkBufferCreateInfo buf_info = {};
1707     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1708     buf_info.pNext = NULL;
1709     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1710     buf_info.size = 256;
1711     buf_info.queueFamilyIndexCount = 0;
1712     buf_info.pQueueFamilyIndices = NULL;
1713     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1714     buf_info.flags = 0;
1715     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1716     ASSERT_VK_SUCCESS(err);
1717
1718     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
1719
1720     VkMemoryAllocateInfo alloc_info = {};
1721     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1722     alloc_info.pNext = NULL;
1723     alloc_info.memoryTypeIndex = 0;
1724
1725     // Ensure memory is big enough for both bindings
1726     alloc_info.allocationSize = 0x10000;
1727
1728     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1729     if (!pass) {
1730         vkDestroyBuffer(m_device->device(), buffer, NULL);
1731         return;
1732     }
1733
1734     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1735     ASSERT_VK_SUCCESS(err);
1736
1737     uint8_t *pData;
1738     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1739     ASSERT_VK_SUCCESS(err);
1740
1741     memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
1742
1743     vkUnmapMemory(m_device->device(), mem);
1744
1745     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
1746     ASSERT_VK_SUCCESS(err);
1747
1748     // NOW, destroy the buffer. Obviously, the resource no longer occupies this
1749     // memory. In fact, it was never used by the GPU.
1750     // Just be be sure, wait for idle.
1751     vkDestroyBuffer(m_device->device(), buffer, NULL);
1752     vkDeviceWaitIdle(m_device->device());
1753
1754     VkImageCreateInfo image_create_info = {};
1755     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1756     image_create_info.pNext = NULL;
1757     image_create_info.imageType = VK_IMAGE_TYPE_2D;
1758     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1759     image_create_info.extent.width = 64;
1760     image_create_info.extent.height = 64;
1761     image_create_info.extent.depth = 1;
1762     image_create_info.mipLevels = 1;
1763     image_create_info.arrayLayers = 1;
1764     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1765     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
1766     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1767     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1768     image_create_info.queueFamilyIndexCount = 0;
1769     image_create_info.pQueueFamilyIndices = NULL;
1770     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1771     image_create_info.flags = 0;
1772
1773     VkMemoryAllocateInfo mem_alloc = {};
1774     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1775     mem_alloc.pNext = NULL;
1776     mem_alloc.allocationSize = 0;
1777     mem_alloc.memoryTypeIndex = 0;
1778
1779     /* Create a mappable image.  It will be the texture if linear images are ok
1780     * to be textures or it will be the staging image if they are not.
1781     */
1782     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1783     ASSERT_VK_SUCCESS(err);
1784
1785     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
1786
1787     mem_alloc.allocationSize = mem_reqs.size;
1788
1789     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1790     if (!pass) {
1791         vkDestroyImage(m_device->device(), image, NULL);
1792         return;
1793     }
1794
1795     // VALIDATION FAILURE:
1796     err = vkBindImageMemory(m_device->device(), image, mem, 0);
1797     ASSERT_VK_SUCCESS(err);
1798
1799     m_errorMonitor->VerifyNotFound();
1800
1801     vkFreeMemory(m_device->device(), mem, NULL);
1802     vkDestroyBuffer(m_device->device(), buffer, NULL);
1803     vkDestroyImage(m_device->device(), image, NULL);
1804 }
1805
1806 TEST_F(VkLayerTest, InvalidMemoryAliasing) {
1807     TEST_DESCRIPTION("Create a buffer and image, allocate memory, and bind the "
1808                      "buffer and image to memory such that they will alias.");
1809     VkResult err;
1810     bool pass;
1811     ASSERT_NO_FATAL_FAILURE(InitState());
1812
1813     VkBuffer buffer, buffer2;
1814     VkImage image;
1815     VkImage image2;
1816     VkDeviceMemory mem;     // buffer will be bound first
1817     VkDeviceMemory mem_img; // image bound first
1818     VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
1819
1820     VkBufferCreateInfo buf_info = {};
1821     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1822     buf_info.pNext = NULL;
1823     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1824     buf_info.size = 256;
1825     buf_info.queueFamilyIndexCount = 0;
1826     buf_info.pQueueFamilyIndices = NULL;
1827     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1828     buf_info.flags = 0;
1829     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1830     ASSERT_VK_SUCCESS(err);
1831
1832     vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs);
1833
1834     VkImageCreateInfo image_create_info = {};
1835     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1836     image_create_info.pNext = NULL;
1837     image_create_info.imageType = VK_IMAGE_TYPE_2D;
1838     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1839     image_create_info.extent.width = 64;
1840     image_create_info.extent.height = 64;
1841     image_create_info.extent.depth = 1;
1842     image_create_info.mipLevels = 1;
1843     image_create_info.arrayLayers = 1;
1844     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1845     // Image tiling must be optimal to trigger error when aliasing linear buffer
1846     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1847     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1848     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1849     image_create_info.queueFamilyIndexCount = 0;
1850     image_create_info.pQueueFamilyIndices = NULL;
1851     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1852     image_create_info.flags = 0;
1853
1854     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1855     ASSERT_VK_SUCCESS(err);
1856     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
1857     ASSERT_VK_SUCCESS(err);
1858
1859     vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
1860
1861     VkMemoryAllocateInfo alloc_info = {};
1862     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1863     alloc_info.pNext = NULL;
1864     alloc_info.memoryTypeIndex = 0;
1865     // Ensure memory is big enough for both bindings
1866     alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size;
1867     pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info,
1868                                            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1869     if (!pass) {
1870         vkDestroyBuffer(m_device->device(), buffer, NULL);
1871         vkDestroyImage(m_device->device(), image, NULL);
1872         return;
1873     }
1874     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1875     ASSERT_VK_SUCCESS(err);
1876     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
1877     ASSERT_VK_SUCCESS(err);
1878
1879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is aliased with linear buffer 0x");
1880     // VALIDATION FAILURE due to image mapping overlapping buffer mapping
1881     err = vkBindImageMemory(m_device->device(), image, mem, 0);
1882     m_errorMonitor->VerifyFound();
1883
1884     // Now correctly bind image2 to second mem allocation before incorrectly
1885     // aliasing buffer2
1886     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2);
1887     ASSERT_VK_SUCCESS(err);
1888     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img);
1889     ASSERT_VK_SUCCESS(err);
1890     err = vkBindImageMemory(m_device->device(), image2, mem_img, 0);
1891     ASSERT_VK_SUCCESS(err);
1892     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is aliased with non-linear image 0x");
1893     err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0);
1894     m_errorMonitor->VerifyFound();
1895
1896     vkDestroyBuffer(m_device->device(), buffer, NULL);
1897     vkDestroyBuffer(m_device->device(), buffer2, NULL);
1898     vkDestroyImage(m_device->device(), image, NULL);
1899     vkDestroyImage(m_device->device(), image2, NULL);
1900     vkFreeMemory(m_device->device(), mem, NULL);
1901     vkFreeMemory(m_device->device(), mem_img, NULL);
1902 }
1903
1904 TEST_F(VkLayerTest, InvalidMemoryMapping) {
1905     TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");
1906     VkResult err;
1907     bool pass;
1908     ASSERT_NO_FATAL_FAILURE(InitState());
1909
1910     VkBuffer buffer;
1911     VkDeviceMemory mem;
1912     VkMemoryRequirements mem_reqs;
1913
1914     VkBufferCreateInfo buf_info = {};
1915     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1916     buf_info.pNext = NULL;
1917     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1918     buf_info.size = 256;
1919     buf_info.queueFamilyIndexCount = 0;
1920     buf_info.pQueueFamilyIndices = NULL;
1921     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1922     buf_info.flags = 0;
1923     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1924     ASSERT_VK_SUCCESS(err);
1925
1926     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
1927     VkMemoryAllocateInfo alloc_info = {};
1928     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1929     alloc_info.pNext = NULL;
1930     alloc_info.memoryTypeIndex = 0;
1931
1932     // Ensure memory is big enough for both bindings
1933     static const VkDeviceSize allocation_size = 0x10000;
1934     alloc_info.allocationSize = allocation_size;
1935     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1936     if (!pass) {
1937         vkDestroyBuffer(m_device->device(), buffer, NULL);
1938         return;
1939     }
1940     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1941     ASSERT_VK_SUCCESS(err);
1942
1943     uint8_t *pData;
1944     // Attempt to map memory size 0 is invalid
1945     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero");
1946     err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData);
1947     m_errorMonitor->VerifyFound();
1948     // Map memory twice
1949     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1950     ASSERT_VK_SUCCESS(err);
1951     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1952                                          "VkMapMemory: Attempting to map memory on an already-mapped object ");
1953     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1954     m_errorMonitor->VerifyFound();
1955
1956     // Unmap the memory to avoid re-map error
1957     vkUnmapMemory(m_device->device(), mem);
1958     // overstep allocation with VK_WHOLE_SIZE
1959     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1960                                          " with size of VK_WHOLE_SIZE oversteps total array size 0x");
1961     err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData);
1962     m_errorMonitor->VerifyFound();
1963     // overstep allocation w/o VK_WHOLE_SIZE
1964     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x");
1965     err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData);
1966     m_errorMonitor->VerifyFound();
1967     // Now error due to unmapping memory that's not mapped
1968     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: ");
1969     vkUnmapMemory(m_device->device(), mem);
1970     m_errorMonitor->VerifyFound();
1971     // Now map memory and cause errors due to flushing invalid ranges
1972     err = vkMapMemory(m_device->device(), mem, 16, VK_WHOLE_SIZE, 0, (void **)&pData);
1973     ASSERT_VK_SUCCESS(err);
1974     VkMappedMemoryRange mmr = {};
1975     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1976     mmr.memory = mem;
1977     mmr.offset = 15; // Error b/c offset less than offset of mapped mem
1978     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") is less than Memory Object's offset (");
1979     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
1980     m_errorMonitor->VerifyFound();
1981     // Now flush range that oversteps mapped range
1982     vkUnmapMemory(m_device->device(), mem);
1983     err = vkMapMemory(m_device->device(), mem, 0, 256, 0, (void **)&pData);
1984     ASSERT_VK_SUCCESS(err);
1985     mmr.offset = 16;
1986     mmr.size = 256; // flushing bounds (272) exceed mapped bounds (256)
1987     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") exceeds the Memory Object's upper-bound (");
1988     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
1989     m_errorMonitor->VerifyFound();
1990
1991     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
1992                                            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
1993     if (!pass) {
1994         vkFreeMemory(m_device->device(), mem, NULL);
1995         vkDestroyBuffer(m_device->device(), buffer, NULL);
1996         return;
1997     }
1998     // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of
1999     //  MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver()
2000
2001     vkDestroyBuffer(m_device->device(), buffer, NULL);
2002     vkFreeMemory(m_device->device(), mem, NULL);
2003 }
2004
2005 TEST_F(VkLayerTest, NonCoherentMemoryMapping) {
2006
2007     TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory "
2008                      "mapping while using VK_WHOLE_SIZE does not cause access "
2009                      "violations");
2010     VkResult err;
2011     uint8_t *pData;
2012     ASSERT_NO_FATAL_FAILURE(InitState());
2013
2014     VkDeviceMemory mem;
2015     VkMemoryRequirements mem_reqs;
2016     mem_reqs.memoryTypeBits = 0xFFFFFFFF;
2017     VkMemoryAllocateInfo alloc_info = {};
2018     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2019     alloc_info.pNext = NULL;
2020     alloc_info.memoryTypeIndex = 0;
2021
2022     static const VkDeviceSize allocation_size = 0x1000;
2023     alloc_info.allocationSize = allocation_size;
2024
2025     // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
2026     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
2027                                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2028     if (!pass) {
2029         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
2030                                                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2031                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2032         if (!pass) {
2033             pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
2034                                                    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
2035                                                        VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2036                                                    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2037             if (!pass) {
2038                 return;
2039             }
2040         }
2041     }
2042
2043     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2044     ASSERT_VK_SUCCESS(err);
2045
2046     // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire
2047     // mapped range
2048     m_errorMonitor->ExpectSuccess();
2049     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
2050     ASSERT_VK_SUCCESS(err);
2051     VkMappedMemoryRange mmr = {};
2052     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2053     mmr.memory = mem;
2054     mmr.offset = 0;
2055     mmr.size = VK_WHOLE_SIZE;
2056     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2057     ASSERT_VK_SUCCESS(err);
2058     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2059     ASSERT_VK_SUCCESS(err);
2060     m_errorMonitor->VerifyNotFound();
2061     vkUnmapMemory(m_device->device(), mem);
2062
2063     // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire
2064     // mapped range
2065     m_errorMonitor->ExpectSuccess();
2066     err = vkMapMemory(m_device->device(), mem, 13, VK_WHOLE_SIZE, 0, (void **)&pData);
2067     ASSERT_VK_SUCCESS(err);
2068     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2069     mmr.memory = mem;
2070     mmr.offset = 13;
2071     mmr.size = VK_WHOLE_SIZE;
2072     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2073     ASSERT_VK_SUCCESS(err);
2074     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2075     ASSERT_VK_SUCCESS(err);
2076     m_errorMonitor->VerifyNotFound();
2077     vkUnmapMemory(m_device->device(), mem);
2078
2079     // Map with prime offset and size
2080     // Flush/Invalidate subrange of mapped area with prime offset and size
2081     m_errorMonitor->ExpectSuccess();
2082     err = vkMapMemory(m_device->device(), mem, allocation_size - 137, 109, 0, (void **)&pData);
2083     ASSERT_VK_SUCCESS(err);
2084     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2085     mmr.memory = mem;
2086     mmr.offset = allocation_size - 107;
2087     mmr.size = 61;
2088     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2089     ASSERT_VK_SUCCESS(err);
2090     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
2091     ASSERT_VK_SUCCESS(err);
2092     m_errorMonitor->VerifyNotFound();
2093     vkUnmapMemory(m_device->device(), mem);
2094
2095     // Map without offset and flush WHOLE_SIZE with two separate offsets
2096     m_errorMonitor->ExpectSuccess();
2097     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
2098     ASSERT_VK_SUCCESS(err);
2099     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2100     mmr.memory = mem;
2101     mmr.offset = allocation_size - 100;
2102     mmr.size = VK_WHOLE_SIZE;
2103     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2104     ASSERT_VK_SUCCESS(err);
2105     mmr.offset = allocation_size - 200;
2106     mmr.size = VK_WHOLE_SIZE;
2107     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2108     ASSERT_VK_SUCCESS(err);
2109     m_errorMonitor->VerifyNotFound();
2110     vkUnmapMemory(m_device->device(), mem);
2111
2112     vkFreeMemory(m_device->device(), mem, NULL);
2113 }
2114
2115 TEST_F(VkLayerTest, EnableWsiBeforeUse) {
2116     VkResult err;
2117     bool pass;
2118
2119     // FIXME: After we turn on this code for non-Linux platforms, uncomment the
2120     // following declaration (which is temporarily being moved below):
2121     //    VkSurfaceKHR surface = VK_NULL_HANDLE;
2122     VkSwapchainKHR swapchain = VK_NULL_HANDLE;
2123     VkSwapchainCreateInfoKHR swapchain_create_info = {};
2124     uint32_t swapchain_image_count = 0;
2125     //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
2126     uint32_t image_index = 0;
2127     //    VkPresentInfoKHR present_info = {};
2128
2129     ASSERT_NO_FATAL_FAILURE(InitState());
2130
2131 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
2132 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
2133     // Use the functions from the VK_KHR_android_surface extension without
2134     // enabling that extension:
2135
2136     // Create a surface:
2137     VkAndroidSurfaceCreateInfoKHR android_create_info = {};
2138     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2139     err = vkCreateAndroidSurfaceKHR(instance(), &android_create_info, NULL, &surface);
2140     pass = (err != VK_SUCCESS);
2141     ASSERT_TRUE(pass);
2142     m_errorMonitor->VerifyFound();
2143 #endif // VK_USE_PLATFORM_ANDROID_KHR
2144
2145 #if defined(VK_USE_PLATFORM_MIR_KHR)
2146     // Use the functions from the VK_KHR_mir_surface extension without enabling
2147     // that extension:
2148
2149     // Create a surface:
2150     VkMirSurfaceCreateInfoKHR mir_create_info = {};
2151     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2152     err = vkCreateMirSurfaceKHR(instance(), &mir_create_info, NULL, &surface);
2153     pass = (err != VK_SUCCESS);
2154     ASSERT_TRUE(pass);
2155     m_errorMonitor->VerifyFound();
2156
2157     // Tell whether an mir_connection supports presentation:
2158     MirConnection *mir_connection = NULL;
2159     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2160     vkGetPhysicalDeviceMirPresentationSupportKHR(gpu(), 0, mir_connection, visual_id);
2161     m_errorMonitor->VerifyFound();
2162 #endif // VK_USE_PLATFORM_MIR_KHR
2163
2164 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
2165     // Use the functions from the VK_KHR_wayland_surface extension without
2166     // enabling that extension:
2167
2168     // Create a surface:
2169     VkWaylandSurfaceCreateInfoKHR wayland_create_info = {};
2170     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2171     err = vkCreateWaylandSurfaceKHR(instance(), &wayland_create_info, NULL, &surface);
2172     pass = (err != VK_SUCCESS);
2173     ASSERT_TRUE(pass);
2174     m_errorMonitor->VerifyFound();
2175
2176     // Tell whether an wayland_display supports presentation:
2177     struct wl_display wayland_display = {};
2178     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2179     vkGetPhysicalDeviceWaylandPresentationSupportKHR(gpu(), 0, &wayland_display);
2180     m_errorMonitor->VerifyFound();
2181 #endif // VK_USE_PLATFORM_WAYLAND_KHR
2182 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
2183
2184 #if defined(VK_USE_PLATFORM_WIN32_KHR)
2185     // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED
2186     // TO NON-LINUX PLATFORMS:
2187     VkSurfaceKHR surface = VK_NULL_HANDLE;
2188     // Use the functions from the VK_KHR_win32_surface extension without
2189     // enabling that extension:
2190
2191     // Create a surface:
2192     VkWin32SurfaceCreateInfoKHR win32_create_info = {};
2193     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2194     err = vkCreateWin32SurfaceKHR(instance(), &win32_create_info, NULL, &surface);
2195     pass = (err != VK_SUCCESS);
2196     ASSERT_TRUE(pass);
2197     m_errorMonitor->VerifyFound();
2198
2199     // Tell whether win32 supports presentation:
2200     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2201     vkGetPhysicalDeviceWin32PresentationSupportKHR(gpu(), 0);
2202     m_errorMonitor->VerifyFound();
2203 // Set this (for now, until all platforms are supported and tested):
2204 #define NEED_TO_TEST_THIS_ON_PLATFORM
2205 #endif // VK_USE_PLATFORM_WIN32_KHR
2206
2207 #if defined(VK_USE_PLATFORM_XCB_KHR)
2208     // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED
2209     // TO NON-LINUX PLATFORMS:
2210     VkSurfaceKHR surface = VK_NULL_HANDLE;
2211     // Use the functions from the VK_KHR_xcb_surface extension without enabling
2212     // that extension:
2213
2214     // Create a surface:
2215     VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
2216     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2217     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2218     pass = (err != VK_SUCCESS);
2219     ASSERT_TRUE(pass);
2220     m_errorMonitor->VerifyFound();
2221
2222     // Tell whether an xcb_visualid_t supports presentation:
2223     xcb_connection_t *xcb_connection = NULL;
2224     xcb_visualid_t visual_id = 0;
2225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2226     vkGetPhysicalDeviceXcbPresentationSupportKHR(gpu(), 0, xcb_connection, visual_id);
2227     m_errorMonitor->VerifyFound();
2228 // Set this (for now, until all platforms are supported and tested):
2229 #define NEED_TO_TEST_THIS_ON_PLATFORM
2230 #endif // VK_USE_PLATFORM_XCB_KHR
2231
2232 #if defined(VK_USE_PLATFORM_XLIB_KHR)
2233     // Use the functions from the VK_KHR_xlib_surface extension without enabling
2234     // that extension:
2235
2236     // Create a surface:
2237     VkXlibSurfaceCreateInfoKHR xlib_create_info = {};
2238     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2239     err = vkCreateXlibSurfaceKHR(instance(), &xlib_create_info, NULL, &surface);
2240     pass = (err != VK_SUCCESS);
2241     ASSERT_TRUE(pass);
2242     m_errorMonitor->VerifyFound();
2243
2244     // Tell whether an Xlib VisualID supports presentation:
2245     Display *dpy = NULL;
2246     VisualID visual = 0;
2247     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2248     vkGetPhysicalDeviceXlibPresentationSupportKHR(gpu(), 0, dpy, visual);
2249     m_errorMonitor->VerifyFound();
2250 // Set this (for now, until all platforms are supported and tested):
2251 #define NEED_TO_TEST_THIS_ON_PLATFORM
2252 #endif // VK_USE_PLATFORM_XLIB_KHR
2253
2254 // Use the functions from the VK_KHR_surface extension without enabling
2255 // that extension:
2256
2257 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
2258     // Destroy a surface:
2259     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2260     vkDestroySurfaceKHR(instance(), surface, NULL);
2261     m_errorMonitor->VerifyFound();
2262
2263     // Check if surface supports presentation:
2264     VkBool32 supported = false;
2265     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2266     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2267     pass = (err != VK_SUCCESS);
2268     ASSERT_TRUE(pass);
2269     m_errorMonitor->VerifyFound();
2270
2271     // Check surface capabilities:
2272     VkSurfaceCapabilitiesKHR capabilities = {};
2273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2274     err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &capabilities);
2275     pass = (err != VK_SUCCESS);
2276     ASSERT_TRUE(pass);
2277     m_errorMonitor->VerifyFound();
2278
2279     // Check surface formats:
2280     uint32_t format_count = 0;
2281     VkSurfaceFormatKHR *formats = NULL;
2282     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2283     err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &format_count, formats);
2284     pass = (err != VK_SUCCESS);
2285     ASSERT_TRUE(pass);
2286     m_errorMonitor->VerifyFound();
2287
2288     // Check surface present modes:
2289     uint32_t present_mode_count = 0;
2290     VkSurfaceFormatKHR *present_modes = NULL;
2291     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2292     err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &present_mode_count, present_modes);
2293     pass = (err != VK_SUCCESS);
2294     ASSERT_TRUE(pass);
2295     m_errorMonitor->VerifyFound();
2296 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
2297
2298     // Use the functions from the VK_KHR_swapchain extension without enabling
2299     // that extension:
2300
2301     // Create a swapchain:
2302     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2303     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2304     swapchain_create_info.pNext = NULL;
2305     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2306     pass = (err != VK_SUCCESS);
2307     ASSERT_TRUE(pass);
2308     m_errorMonitor->VerifyFound();
2309
2310     // Get the images from the swapchain:
2311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2312     err = vkGetSwapchainImagesKHR(m_device->device(), swapchain, &swapchain_image_count, NULL);
2313     pass = (err != VK_SUCCESS);
2314     ASSERT_TRUE(pass);
2315     m_errorMonitor->VerifyFound();
2316
2317     // Add a fence to avoid (justifiable) error about not providing fence OR semaphore
2318     VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2319     VkFence fence;
2320     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2321
2322     // Try to acquire an image:
2323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2324     err = vkAcquireNextImageKHR(m_device->device(), swapchain, 0, VK_NULL_HANDLE, fence, &image_index);
2325     pass = (err != VK_SUCCESS);
2326     ASSERT_TRUE(pass);
2327     m_errorMonitor->VerifyFound();
2328
2329     vkDestroyFence(m_device->device(), fence, nullptr);
2330
2331     // Try to present an image:
2332     //
2333     // NOTE: Currently can't test this because a real swapchain is needed (as
2334     // opposed to the fake one we created) in order for the layer to lookup the
2335     // VkDevice used to enable the extension:
2336
2337     // Destroy the swapchain:
2338     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
2339     vkDestroySwapchainKHR(m_device->device(), swapchain, NULL);
2340     m_errorMonitor->VerifyFound();
2341 }
2342
2343 TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) {
2344
2345 #if defined(VK_USE_PLATFORM_XCB_KHR)
2346     VkSurfaceKHR surface = VK_NULL_HANDLE;
2347
2348     VkResult err;
2349     bool pass;
2350     VkSwapchainKHR swapchain = VK_NULL_HANDLE;
2351     VkSwapchainCreateInfoKHR swapchain_create_info = {};
2352     //    uint32_t swapchain_image_count = 0;
2353     //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
2354     //    uint32_t image_index = 0;
2355     //    VkPresentInfoKHR present_info = {};
2356
2357     ASSERT_NO_FATAL_FAILURE(InitState());
2358
2359     // Use the create function from one of the VK_KHR_*_surface extension in
2360     // order to create a surface, testing all known errors in the process,
2361     // before successfully creating a surface:
2362     // First, try to create a surface without a VkXcbSurfaceCreateInfoKHR:
2363     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo specified as NULL");
2364     err = vkCreateXcbSurfaceKHR(instance(), NULL, NULL, &surface);
2365     pass = (err != VK_SUCCESS);
2366     ASSERT_TRUE(pass);
2367     m_errorMonitor->VerifyFound();
2368
2369     // Next, try to create a surface with the wrong
2370     // VkXcbSurfaceCreateInfoKHR::sType:
2371     VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
2372     xcb_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2373     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2374     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2375     pass = (err != VK_SUCCESS);
2376     ASSERT_TRUE(pass);
2377     m_errorMonitor->VerifyFound();
2378
2379     // Create a native window, and then correctly create a surface:
2380     xcb_connection_t *connection;
2381     xcb_screen_t *screen;
2382     xcb_window_t xcb_window;
2383     xcb_intern_atom_reply_t *atom_wm_delete_window;
2384
2385     const xcb_setup_t *setup;
2386     xcb_screen_iterator_t iter;
2387     int scr;
2388     uint32_t value_mask, value_list[32];
2389     int width = 1;
2390     int height = 1;
2391
2392     connection = xcb_connect(NULL, &scr);
2393     ASSERT_TRUE(connection != NULL);
2394     setup = xcb_get_setup(connection);
2395     iter = xcb_setup_roots_iterator(setup);
2396     while (scr-- > 0)
2397         xcb_screen_next(&iter);
2398     screen = iter.data;
2399
2400     xcb_window = xcb_generate_id(connection);
2401
2402     value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
2403     value_list[0] = screen->black_pixel;
2404     value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
2405
2406     xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0,
2407                       XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list);
2408
2409     /* Magic code that will send notification when window is destroyed */
2410     xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
2411     xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0);
2412
2413     xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
2414     atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
2415     xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom);
2416     free(reply);
2417
2418     xcb_map_window(connection, xcb_window);
2419
2420     // Force the x/y coordinates to 100,100 results are identical in consecutive
2421     // runs
2422     const uint32_t coords[] = {100, 100};
2423     xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
2424
2425     // Finally, try to correctly create a surface:
2426     xcb_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
2427     xcb_create_info.pNext = NULL;
2428     xcb_create_info.flags = 0;
2429     xcb_create_info.connection = connection;
2430     xcb_create_info.window = xcb_window;
2431     err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
2432     pass = (err == VK_SUCCESS);
2433     ASSERT_TRUE(pass);
2434
2435     // Check if surface supports presentation:
2436
2437     // 1st, do so without having queried the queue families:
2438     VkBool32 supported = false;
2439     // TODO: Get the following error to come out:
2440     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2441                                          "called before calling the vkGetPhysicalDeviceQueueFamilyProperties "
2442                                          "function");
2443     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2444     pass = (err != VK_SUCCESS);
2445     //    ASSERT_TRUE(pass);
2446     //    m_errorMonitor->VerifyFound();
2447
2448     // Next, query a queue family index that's too large:
2449     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2450     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 100000, surface, &supported);
2451     pass = (err != VK_SUCCESS);
2452     ASSERT_TRUE(pass);
2453     m_errorMonitor->VerifyFound();
2454
2455     // Finally, do so correctly:
2456     // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2457     // SUPPORTED
2458     err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2459     pass = (err == VK_SUCCESS);
2460     ASSERT_TRUE(pass);
2461
2462     // Before proceeding, try to create a swapchain without having called
2463     // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
2464     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2465     swapchain_create_info.pNext = NULL;
2466     swapchain_create_info.flags = 0;
2467     swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2468     swapchain_create_info.surface = surface;
2469     swapchain_create_info.imageArrayLayers = 1;
2470     swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
2471     swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
2472     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2473                                          "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
2474     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2475     pass = (err != VK_SUCCESS);
2476     ASSERT_TRUE(pass);
2477     m_errorMonitor->VerifyFound();
2478
2479     // Get the surface capabilities:
2480     VkSurfaceCapabilitiesKHR surface_capabilities;
2481
2482     // Do so correctly (only error logged by this entrypoint is if the
2483     // extension isn't enabled):
2484     err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
2485     pass = (err == VK_SUCCESS);
2486     ASSERT_TRUE(pass);
2487
2488     // Get the surface formats:
2489     uint32_t surface_format_count;
2490
2491     // First, try without a pointer to surface_format_count:
2492     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
2493                                                                         "specified as NULL");
2494     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
2495     pass = (err == VK_SUCCESS);
2496     ASSERT_TRUE(pass);
2497     m_errorMonitor->VerifyFound();
2498
2499     // Next, call with a non-NULL pSurfaceFormats, even though we haven't
2500     // correctly done a 1st try (to get the count):
2501     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2502     surface_format_count = 0;
2503     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
2504     pass = (err == VK_SUCCESS);
2505     ASSERT_TRUE(pass);
2506     m_errorMonitor->VerifyFound();
2507
2508     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2509     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2510     pass = (err == VK_SUCCESS);
2511     ASSERT_TRUE(pass);
2512
2513     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2514     VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
2515
2516     // Next, do a 2nd try with surface_format_count being set too high:
2517     surface_format_count += 5;
2518     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2519     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2520     pass = (err == VK_SUCCESS);
2521     ASSERT_TRUE(pass);
2522     m_errorMonitor->VerifyFound();
2523
2524     // Finally, do a correct 1st and 2nd try:
2525     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2526     pass = (err == VK_SUCCESS);
2527     ASSERT_TRUE(pass);
2528     vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2529     pass = (err == VK_SUCCESS);
2530     ASSERT_TRUE(pass);
2531
2532     // Get the surface present modes:
2533     uint32_t surface_present_mode_count;
2534
2535     // First, try without a pointer to surface_format_count:
2536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
2537                                                                         "specified as NULL");
2538
2539     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
2540     pass = (err == VK_SUCCESS);
2541     ASSERT_TRUE(pass);
2542     m_errorMonitor->VerifyFound();
2543
2544     // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
2545     // correctly done a 1st try (to get the count):
2546     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2547     surface_present_mode_count = 0;
2548     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
2549                                               (VkPresentModeKHR *)&surface_present_mode_count);
2550     pass = (err == VK_SUCCESS);
2551     ASSERT_TRUE(pass);
2552     m_errorMonitor->VerifyFound();
2553
2554     // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2555     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2556     pass = (err == VK_SUCCESS);
2557     ASSERT_TRUE(pass);
2558
2559     // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2560     VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
2561
2562     // Next, do a 2nd try with surface_format_count being set too high:
2563     surface_present_mode_count += 5;
2564     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2565     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2566     pass = (err == VK_SUCCESS);
2567     ASSERT_TRUE(pass);
2568     m_errorMonitor->VerifyFound();
2569
2570     // Finally, do a correct 1st and 2nd try:
2571     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2572     pass = (err == VK_SUCCESS);
2573     ASSERT_TRUE(pass);
2574     vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2575     pass = (err == VK_SUCCESS);
2576     ASSERT_TRUE(pass);
2577
2578     // Create a swapchain:
2579
2580     // First, try without a pointer to swapchain_create_info:
2581     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
2582                                                                         "specified as NULL");
2583
2584     err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
2585     pass = (err != VK_SUCCESS);
2586     ASSERT_TRUE(pass);
2587     m_errorMonitor->VerifyFound();
2588
2589     // Next, call with a non-NULL swapchain_create_info, that has the wrong
2590     // sType:
2591     swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2592     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2593
2594     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2595     pass = (err != VK_SUCCESS);
2596     ASSERT_TRUE(pass);
2597     m_errorMonitor->VerifyFound();
2598
2599     // Next, call with a NULL swapchain pointer:
2600     swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2601     swapchain_create_info.pNext = NULL;
2602     swapchain_create_info.flags = 0;
2603     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
2604                                                                         "specified as NULL");
2605
2606     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
2607     pass = (err != VK_SUCCESS);
2608     ASSERT_TRUE(pass);
2609     m_errorMonitor->VerifyFound();
2610
2611     // TODO: Enhance swapchain layer so that
2612     // swapchain_create_info.queueFamilyIndexCount is checked against something?
2613
2614     // Next, call with a queue family index that's too large:
2615     uint32_t queueFamilyIndex[2] = {100000, 0};
2616     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2617     swapchain_create_info.queueFamilyIndexCount = 2;
2618     swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
2619     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2620     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2621     pass = (err != VK_SUCCESS);
2622     ASSERT_TRUE(pass);
2623     m_errorMonitor->VerifyFound();
2624
2625     // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
2626     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2627     swapchain_create_info.queueFamilyIndexCount = 1;
2628     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2629                                          "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
2630                                          "pCreateInfo->pQueueFamilyIndices).");
2631     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2632     pass = (err != VK_SUCCESS);
2633     ASSERT_TRUE(pass);
2634     m_errorMonitor->VerifyFound();
2635
2636     // Next, call with an invalid imageSharingMode:
2637     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
2638     swapchain_create_info.queueFamilyIndexCount = 1;
2639     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2640                                          "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
2641     err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2642     pass = (err != VK_SUCCESS);
2643     ASSERT_TRUE(pass);
2644     m_errorMonitor->VerifyFound();
2645     // Fix for the future:
2646     // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2647     // SUPPORTED
2648     swapchain_create_info.queueFamilyIndexCount = 0;
2649     queueFamilyIndex[0] = 0;
2650     swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
2651
2652     // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
2653     // Get the images from a swapchain:
2654     // Acquire an image from a swapchain:
2655     // Present an image to a swapchain:
2656     // Destroy the swapchain:
2657
2658     // TODOs:
2659     //
2660     // - Try destroying the device without first destroying the swapchain
2661     //
2662     // - Try destroying the device without first destroying the surface
2663     //
2664     // - Try destroying the surface without first destroying the swapchain
2665
2666     // Destroy the surface:
2667     vkDestroySurfaceKHR(instance(), surface, NULL);
2668
2669     // Tear down the window:
2670     xcb_destroy_window(connection, xcb_window);
2671     xcb_disconnect(connection);
2672
2673 #else  // VK_USE_PLATFORM_XCB_KHR
2674     return;
2675 #endif // VK_USE_PLATFORM_XCB_KHR
2676 }
2677
2678 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2679     VkResult err;
2680     bool pass;
2681
2682     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2683                                          "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2684
2685     ASSERT_NO_FATAL_FAILURE(InitState());
2686
2687     // Create an image, allocate memory, free it, and then try to bind it
2688     VkImage image;
2689     VkDeviceMemory mem;
2690     VkMemoryRequirements mem_reqs;
2691
2692     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2693     const int32_t tex_width = 32;
2694     const int32_t tex_height = 32;
2695
2696     VkImageCreateInfo image_create_info = {};
2697     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2698     image_create_info.pNext = NULL;
2699     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2700     image_create_info.format = tex_format;
2701     image_create_info.extent.width = tex_width;
2702     image_create_info.extent.height = tex_height;
2703     image_create_info.extent.depth = 1;
2704     image_create_info.mipLevels = 1;
2705     image_create_info.arrayLayers = 1;
2706     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2707     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2708     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2709     image_create_info.flags = 0;
2710     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2711
2712     VkMemoryAllocateInfo mem_alloc = {};
2713     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2714     mem_alloc.pNext = NULL;
2715     mem_alloc.allocationSize = 0;
2716
2717     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2718     ASSERT_VK_SUCCESS(err);
2719
2720     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2721
2722     mem_alloc.allocationSize = mem_reqs.size;
2723
2724     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2725     if (!pass) { // If we can't find any unmappable memory this test doesn't
2726                  // make sense
2727         vkDestroyImage(m_device->device(), image, NULL);
2728         return;
2729     }
2730
2731     // allocate memory
2732     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2733     ASSERT_VK_SUCCESS(err);
2734
2735     // Try to bind free memory that has been freed
2736     err = vkBindImageMemory(m_device->device(), image, mem, 0);
2737     ASSERT_VK_SUCCESS(err);
2738
2739     // Map memory as if to initialize the image
2740     void *mappedAddress = NULL;
2741     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2742
2743     m_errorMonitor->VerifyFound();
2744
2745     vkDestroyImage(m_device->device(), image, NULL);
2746     vkFreeMemory(m_device->device(), mem, NULL);
2747 }
2748
2749 TEST_F(VkLayerTest, RebindMemory) {
2750     VkResult err;
2751     bool pass;
2752
2753     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2754
2755     ASSERT_NO_FATAL_FAILURE(InitState());
2756
2757     // Create an image, allocate memory, free it, and then try to bind it
2758     VkImage image;
2759     VkDeviceMemory mem1;
2760     VkDeviceMemory mem2;
2761     VkMemoryRequirements mem_reqs;
2762
2763     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2764     const int32_t tex_width = 32;
2765     const int32_t tex_height = 32;
2766
2767     VkImageCreateInfo image_create_info = {};
2768     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2769     image_create_info.pNext = NULL;
2770     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2771     image_create_info.format = tex_format;
2772     image_create_info.extent.width = tex_width;
2773     image_create_info.extent.height = tex_height;
2774     image_create_info.extent.depth = 1;
2775     image_create_info.mipLevels = 1;
2776     image_create_info.arrayLayers = 1;
2777     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2778     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2779     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2780     image_create_info.flags = 0;
2781
2782     VkMemoryAllocateInfo mem_alloc = {};
2783     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2784     mem_alloc.pNext = NULL;
2785     mem_alloc.allocationSize = 0;
2786     mem_alloc.memoryTypeIndex = 0;
2787
2788     // Introduce failure, do NOT set memProps to
2789     // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2790     mem_alloc.memoryTypeIndex = 1;
2791     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2792     ASSERT_VK_SUCCESS(err);
2793
2794     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2795
2796     mem_alloc.allocationSize = mem_reqs.size;
2797     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2798     ASSERT_TRUE(pass);
2799
2800     // allocate 2 memory objects
2801     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2802     ASSERT_VK_SUCCESS(err);
2803     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2804     ASSERT_VK_SUCCESS(err);
2805
2806     // Bind first memory object to Image object
2807     err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2808     ASSERT_VK_SUCCESS(err);
2809
2810     // Introduce validation failure, try to bind a different memory object to
2811     // the same image object
2812     err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2813
2814     m_errorMonitor->VerifyFound();
2815
2816     vkDestroyImage(m_device->device(), image, NULL);
2817     vkFreeMemory(m_device->device(), mem1, NULL);
2818     vkFreeMemory(m_device->device(), mem2, NULL);
2819 }
2820
2821 TEST_F(VkLayerTest, SubmitSignaledFence) {
2822     vk_testing::Fence testFence;
2823
2824     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state.  Fences "
2825                                                                         "must be reset before being submitted");
2826
2827     VkFenceCreateInfo fenceInfo = {};
2828     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2829     fenceInfo.pNext = NULL;
2830     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2831
2832     ASSERT_NO_FATAL_FAILURE(InitState());
2833     ASSERT_NO_FATAL_FAILURE(InitViewport());
2834     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2835
2836     BeginCommandBuffer();
2837     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
2838     EndCommandBuffer();
2839
2840     testFence.init(*m_device, fenceInfo);
2841
2842     VkSubmitInfo submit_info;
2843     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2844     submit_info.pNext = NULL;
2845     submit_info.waitSemaphoreCount = 0;
2846     submit_info.pWaitSemaphores = NULL;
2847     submit_info.pWaitDstStageMask = NULL;
2848     submit_info.commandBufferCount = 1;
2849     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2850     submit_info.signalSemaphoreCount = 0;
2851     submit_info.pSignalSemaphores = NULL;
2852
2853     vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2854     vkQueueWaitIdle(m_device->m_queue);
2855
2856     m_errorMonitor->VerifyFound();
2857 }
2858 // This is a positive test. We used to expect error in this case but spec now
2859 // allows it
2860 TEST_F(VkLayerTest, ResetUnsignaledFence) {
2861     m_errorMonitor->ExpectSuccess();
2862     vk_testing::Fence testFence;
2863     VkFenceCreateInfo fenceInfo = {};
2864     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2865     fenceInfo.pNext = NULL;
2866
2867     ASSERT_NO_FATAL_FAILURE(InitState());
2868     testFence.init(*m_device, fenceInfo);
2869     VkFence fences[1] = {testFence.handle()};
2870     VkResult result = vkResetFences(m_device->device(), 1, fences);
2871     ASSERT_VK_SUCCESS(result);
2872
2873     m_errorMonitor->VerifyNotFound();
2874 }
2875 #if 0 // A few devices have issues with this test so disabling for now
2876 TEST_F(VkLayerTest, LongFenceChain)
2877 {
2878     m_errorMonitor->ExpectSuccess();
2879
2880     ASSERT_NO_FATAL_FAILURE(InitState());
2881     VkResult err;
2882
2883     std::vector<VkFence> fences;
2884
2885     const int chainLength = 32768;
2886
2887     for (int i = 0; i < chainLength; i++) {
2888         VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2889         VkFence fence;
2890         err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2891         ASSERT_VK_SUCCESS(err);
2892
2893         fences.push_back(fence);
2894
2895         VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
2896             0, nullptr, 0, nullptr };
2897         err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2898         ASSERT_VK_SUCCESS(err);
2899
2900     }
2901
2902     // BOOM, stack overflow.
2903     vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
2904
2905     for (auto fence : fences)
2906         vkDestroyFence(m_device->device(), fence, nullptr);
2907
2908     m_errorMonitor->VerifyNotFound();
2909 }
2910 #endif
2911 TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
2912     m_errorMonitor->ExpectSuccess();
2913
2914     ASSERT_NO_FATAL_FAILURE(InitState());
2915     VkResult err;
2916
2917     // Record (empty!) command buffer that can be submitted multiple times
2918     // simultaneously.
2919     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2920                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
2921     m_commandBuffer->BeginCommandBuffer(&cbbi);
2922     m_commandBuffer->EndCommandBuffer();
2923
2924     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2925     VkFence fence;
2926     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2927     ASSERT_VK_SUCCESS(err);
2928
2929     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
2930     VkSemaphore s1, s2;
2931     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
2932     ASSERT_VK_SUCCESS(err);
2933     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
2934     ASSERT_VK_SUCCESS(err);
2935
2936     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
2937     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
2938     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2939     ASSERT_VK_SUCCESS(err);
2940
2941     // Submit CB again, signaling s2.
2942     si.pSignalSemaphores = &s2;
2943     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2944     ASSERT_VK_SUCCESS(err);
2945
2946     // Wait for fence.
2947     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
2948     ASSERT_VK_SUCCESS(err);
2949
2950     // CB is still in flight from second submission, but semaphore s1 is no
2951     // longer in flight. delete it.
2952     vkDestroySemaphore(m_device->device(), s1, nullptr);
2953
2954     m_errorMonitor->VerifyNotFound();
2955
2956     // Force device idle and clean up remaining objects
2957     vkDeviceWaitIdle(m_device->device());
2958     vkDestroySemaphore(m_device->device(), s2, nullptr);
2959     vkDestroyFence(m_device->device(), fence, nullptr);
2960 }
2961
2962 TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
2963     m_errorMonitor->ExpectSuccess();
2964
2965     ASSERT_NO_FATAL_FAILURE(InitState());
2966     VkResult err;
2967
2968     // A fence created signaled
2969     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
2970     VkFence f1;
2971     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
2972     ASSERT_VK_SUCCESS(err);
2973
2974     // A fence created not
2975     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2976     VkFence f2;
2977     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
2978     ASSERT_VK_SUCCESS(err);
2979
2980     // Submit the unsignaled fence
2981     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
2982     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
2983
2984     // Wait on both fences, with signaled first.
2985     VkFence fences[] = {f1, f2};
2986     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
2987
2988     // Should have both retired!
2989     vkDestroyFence(m_device->device(), f1, nullptr);
2990     vkDestroyFence(m_device->device(), f2, nullptr);
2991
2992     m_errorMonitor->VerifyNotFound();
2993 }
2994
2995 TEST_F(VkLayerTest, InvalidUsageBits) {
2996     TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
2997                      "Initialize buffer with wrong usage then perform copy expecting errors "
2998                      "from both the image and the buffer (2 calls)");
2999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3000
3001     ASSERT_NO_FATAL_FAILURE(InitState());
3002     VkImageObj image(m_device);
3003     // Initialize image with USAGE_TRANSIENT_ATTACHMENT
3004     image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3005     ASSERT_TRUE(image.initialized());
3006
3007     VkImageView dsv;
3008     VkImageViewCreateInfo dsvci = {};
3009     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3010     dsvci.image = image.handle();
3011     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3012     dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
3013     dsvci.subresourceRange.layerCount = 1;
3014     dsvci.subresourceRange.baseMipLevel = 0;
3015     dsvci.subresourceRange.levelCount = 1;
3016     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3017
3018     // Create a view with depth / stencil aspect for image with different usage
3019     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3020
3021     m_errorMonitor->VerifyFound();
3022
3023     // Initialize buffer with TRANSFER_DST usage
3024     vk_testing::Buffer buffer;
3025     VkMemoryPropertyFlags reqs = 0;
3026     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3027     VkBufferImageCopy region = {};
3028     region.bufferRowLength = 128;
3029     region.bufferImageHeight = 128;
3030     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3031     region.imageSubresource.layerCount = 1;
3032     region.imageExtent.height = 16;
3033     region.imageExtent.width = 16;
3034     region.imageExtent.depth = 1;
3035
3036     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
3037     // Buffer usage not set to TRANSFER_SRC and image usage not set to
3038     // TRANSFER_DST
3039     BeginCommandBuffer();
3040     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3041                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3042     m_errorMonitor->VerifyFound();
3043
3044     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3045     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3046                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
3047     m_errorMonitor->VerifyFound();
3048 }
3049
3050 TEST_F(VkLayerTest, ValidUsage) {
3051     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
3052                      "doesn't generate validation errors");
3053
3054     ASSERT_NO_FATAL_FAILURE(InitState());
3055
3056     m_errorMonitor->ExpectSuccess();
3057     // Verify that we can create a view with usage INPUT_ATTACHMENT
3058     VkImageObj image(m_device);
3059     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3060     ASSERT_TRUE(image.initialized());
3061     VkImageView imageView;
3062     VkImageViewCreateInfo ivci = {};
3063     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3064     ivci.image = image.handle();
3065     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3066     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3067     ivci.subresourceRange.layerCount = 1;
3068     ivci.subresourceRange.baseMipLevel = 0;
3069     ivci.subresourceRange.levelCount = 1;
3070     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3071
3072     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3073     m_errorMonitor->VerifyNotFound();
3074     vkDestroyImageView(m_device->device(), imageView, NULL);
3075 }
3076 #endif // MEM_TRACKER_TESTS
3077
3078 #if OBJ_TRACKER_TESTS
3079
3080 TEST_F(VkLayerTest, LeakAnObject) {
3081     VkResult err;
3082
3083     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3084
3085     // Note that we have to create a new device since destroying the
3086     // framework's device causes Teardown() to fail and just calling Teardown
3087     // will destroy the errorMonitor.
3088
3089     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3090
3091     ASSERT_NO_FATAL_FAILURE(InitState());
3092
3093     const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
3094     std::vector<VkDeviceQueueCreateInfo> queue_info;
3095     queue_info.reserve(queue_props.size());
3096     std::vector<std::vector<float>> queue_priorities;
3097     for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
3098         VkDeviceQueueCreateInfo qi = {};
3099         qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3100         qi.pNext = NULL;
3101         qi.queueFamilyIndex = i;
3102         qi.queueCount = queue_props[i].queueCount;
3103         queue_priorities.emplace_back(qi.queueCount, 0.0f);
3104         qi.pQueuePriorities = queue_priorities[i].data();
3105         queue_info.push_back(qi);
3106     }
3107
3108     std::vector<const char *> device_extension_names;
3109
3110     // The sacrificial device object
3111     VkDevice testDevice;
3112     VkDeviceCreateInfo device_create_info = {};
3113     auto features = m_device->phy().features();
3114     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3115     device_create_info.pNext = NULL;
3116     device_create_info.queueCreateInfoCount = queue_info.size();
3117     device_create_info.pQueueCreateInfos = queue_info.data();
3118     device_create_info.enabledLayerCount = 0;
3119     device_create_info.ppEnabledLayerNames = NULL;
3120     device_create_info.pEnabledFeatures = &features;
3121     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3122     ASSERT_VK_SUCCESS(err);
3123
3124     VkFence fence;
3125     VkFenceCreateInfo fence_create_info = {};
3126     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3127     fence_create_info.pNext = NULL;
3128     fence_create_info.flags = 0;
3129     err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3130     ASSERT_VK_SUCCESS(err);
3131
3132     // Induce failure by not calling vkDestroyFence
3133     vkDestroyDevice(testDevice, NULL);
3134     m_errorMonitor->VerifyFound();
3135 }
3136
3137 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3138
3139     TEST_DESCRIPTION("Allocate command buffers from one command pool and "
3140                      "attempt to delete them from another.");
3141
3142     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3143
3144     ASSERT_NO_FATAL_FAILURE(InitState());
3145     VkCommandPool command_pool_one;
3146     VkCommandPool command_pool_two;
3147
3148     VkCommandPoolCreateInfo pool_create_info{};
3149     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3150     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3151     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3152
3153     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3154
3155     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3156
3157     VkCommandBuffer command_buffer[9];
3158     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3159     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3160     command_buffer_allocate_info.commandPool = command_pool_one;
3161     command_buffer_allocate_info.commandBufferCount = 9;
3162     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3163     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3164
3165     vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]);
3166
3167     m_errorMonitor->VerifyFound();
3168
3169     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3170     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3171 }
3172
3173 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3174     VkResult err;
3175
3176     TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and "
3177                      "attempt to delete them from another.");
3178
3179     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3180
3181     ASSERT_NO_FATAL_FAILURE(InitState());
3182     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3183
3184     VkDescriptorPoolSize ds_type_count = {};
3185     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3186     ds_type_count.descriptorCount = 1;
3187
3188     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3189     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3190     ds_pool_ci.pNext = NULL;
3191     ds_pool_ci.flags = 0;
3192     ds_pool_ci.maxSets = 1;
3193     ds_pool_ci.poolSizeCount = 1;
3194     ds_pool_ci.pPoolSizes = &ds_type_count;
3195
3196     VkDescriptorPool ds_pool_one;
3197     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
3198     ASSERT_VK_SUCCESS(err);
3199
3200     // Create a second descriptor pool
3201     VkDescriptorPool ds_pool_two;
3202     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two);
3203     ASSERT_VK_SUCCESS(err);
3204
3205     VkDescriptorSetLayoutBinding dsl_binding = {};
3206     dsl_binding.binding = 0;
3207     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3208     dsl_binding.descriptorCount = 1;
3209     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3210     dsl_binding.pImmutableSamplers = NULL;
3211
3212     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3213     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3214     ds_layout_ci.pNext = NULL;
3215     ds_layout_ci.bindingCount = 1;
3216     ds_layout_ci.pBindings = &dsl_binding;
3217
3218     VkDescriptorSetLayout ds_layout;
3219     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3220     ASSERT_VK_SUCCESS(err);
3221
3222     VkDescriptorSet descriptorSet;
3223     VkDescriptorSetAllocateInfo alloc_info = {};
3224     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3225     alloc_info.descriptorSetCount = 1;
3226     alloc_info.descriptorPool = ds_pool_one;
3227     alloc_info.pSetLayouts = &ds_layout;
3228     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3229     ASSERT_VK_SUCCESS(err);
3230
3231     err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet);
3232
3233     m_errorMonitor->VerifyFound();
3234
3235     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3236     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
3237     vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL);
3238 }
3239
3240 TEST_F(VkLayerTest, CreateUnknownObject) {
3241     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3242
3243     TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3244
3245     ASSERT_NO_FATAL_FAILURE(InitState());
3246
3247     // Pass bogus handle into GetImageMemoryRequirements
3248     VkMemoryRequirements mem_reqs;
3249     uint64_t fakeImageHandle = 0xCADECADE;
3250     VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3251
3252     vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3253
3254     m_errorMonitor->VerifyFound();
3255 }
3256
3257 TEST_F(VkLayerTest, PipelineNotBound) {
3258     VkResult err;
3259
3260     TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3261
3262     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object ");
3263
3264     ASSERT_NO_FATAL_FAILURE(InitState());
3265     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3266
3267     VkDescriptorPoolSize ds_type_count = {};
3268     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3269     ds_type_count.descriptorCount = 1;
3270
3271     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3272     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3273     ds_pool_ci.pNext = NULL;
3274     ds_pool_ci.maxSets = 1;
3275     ds_pool_ci.poolSizeCount = 1;
3276     ds_pool_ci.pPoolSizes = &ds_type_count;
3277
3278     VkDescriptorPool ds_pool;
3279     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
3280     ASSERT_VK_SUCCESS(err);
3281
3282     VkDescriptorSetLayoutBinding dsl_binding = {};
3283     dsl_binding.binding = 0;
3284     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3285     dsl_binding.descriptorCount = 1;
3286     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3287     dsl_binding.pImmutableSamplers = NULL;
3288
3289     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3290     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3291     ds_layout_ci.pNext = NULL;
3292     ds_layout_ci.bindingCount = 1;
3293     ds_layout_ci.pBindings = &dsl_binding;
3294
3295     VkDescriptorSetLayout ds_layout;
3296     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3297     ASSERT_VK_SUCCESS(err);
3298
3299     VkDescriptorSet descriptorSet;
3300     VkDescriptorSetAllocateInfo alloc_info = {};
3301     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3302     alloc_info.descriptorSetCount = 1;
3303     alloc_info.descriptorPool = ds_pool;
3304     alloc_info.pSetLayouts = &ds_layout;
3305     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3306     ASSERT_VK_SUCCESS(err);
3307
3308     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
3309     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3310     pipeline_layout_ci.pNext = NULL;
3311     pipeline_layout_ci.setLayoutCount = 1;
3312     pipeline_layout_ci.pSetLayouts = &ds_layout;
3313
3314     VkPipelineLayout pipeline_layout;
3315     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
3316     ASSERT_VK_SUCCESS(err);
3317
3318     VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3319
3320     BeginCommandBuffer();
3321     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3322
3323     m_errorMonitor->VerifyFound();
3324
3325     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
3326     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3327     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
3328 }
3329
3330 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3331     VkResult err;
3332
3333     TEST_DESCRIPTION("Test validation check for an invalid memory type index "
3334                      "during bind[Buffer|Image]Memory time");
3335
3336     ASSERT_NO_FATAL_FAILURE(InitState());
3337
3338     // Create an image, allocate memory, set a bad typeIndex and then try to
3339     // bind it
3340     VkImage image;
3341     VkDeviceMemory mem;
3342     VkMemoryRequirements mem_reqs;
3343     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3344     const int32_t tex_width = 32;
3345     const int32_t tex_height = 32;
3346
3347     VkImageCreateInfo image_create_info = {};
3348     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3349     image_create_info.pNext = NULL;
3350     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3351     image_create_info.format = tex_format;
3352     image_create_info.extent.width = tex_width;
3353     image_create_info.extent.height = tex_height;
3354     image_create_info.extent.depth = 1;
3355     image_create_info.mipLevels = 1;
3356     image_create_info.arrayLayers = 1;
3357     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3358     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3359     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3360     image_create_info.flags = 0;
3361
3362     VkMemoryAllocateInfo mem_alloc = {};
3363     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3364     mem_alloc.pNext = NULL;
3365     mem_alloc.allocationSize = 0;
3366     mem_alloc.memoryTypeIndex = 0;
3367
3368     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3369     ASSERT_VK_SUCCESS(err);
3370
3371     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3372     mem_alloc.allocationSize = mem_reqs.size;
3373
3374     // Introduce Failure, select invalid TypeIndex
3375     VkPhysicalDeviceMemoryProperties memory_info;
3376
3377     vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3378     unsigned int i;
3379     for (i = 0; i < memory_info.memoryTypeCount; i++) {
3380         if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3381             mem_alloc.memoryTypeIndex = i;
3382             break;
3383         }
3384     }
3385     if (i >= memory_info.memoryTypeCount) {
3386         printf("No invalid memory type index could be found; skipped.\n");
3387         vkDestroyImage(m_device->device(), image, NULL);
3388         return;
3389     }
3390
3391     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3392
3393     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3394     ASSERT_VK_SUCCESS(err);
3395
3396     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3397     (void)err;
3398
3399     m_errorMonitor->VerifyFound();
3400
3401     vkDestroyImage(m_device->device(), image, NULL);
3402     vkFreeMemory(m_device->device(), mem, NULL);
3403 }
3404
3405 TEST_F(VkLayerTest, BindInvalidMemory) {
3406     VkResult err;
3407     bool pass;
3408
3409     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object ");
3410
3411     ASSERT_NO_FATAL_FAILURE(InitState());
3412
3413     // Create an image, allocate memory, free it, and then try to bind it
3414     VkImage image;
3415     VkDeviceMemory mem;
3416     VkMemoryRequirements mem_reqs;
3417
3418     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3419     const int32_t tex_width = 32;
3420     const int32_t tex_height = 32;
3421
3422     VkImageCreateInfo image_create_info = {};
3423     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3424     image_create_info.pNext = NULL;
3425     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3426     image_create_info.format = tex_format;
3427     image_create_info.extent.width = tex_width;
3428     image_create_info.extent.height = tex_height;
3429     image_create_info.extent.depth = 1;
3430     image_create_info.mipLevels = 1;
3431     image_create_info.arrayLayers = 1;
3432     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3433     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3434     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3435     image_create_info.flags = 0;
3436
3437     VkMemoryAllocateInfo mem_alloc = {};
3438     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3439     mem_alloc.pNext = NULL;
3440     mem_alloc.allocationSize = 0;
3441     mem_alloc.memoryTypeIndex = 0;
3442
3443     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3444     ASSERT_VK_SUCCESS(err);
3445
3446     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3447
3448     mem_alloc.allocationSize = mem_reqs.size;
3449
3450     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3451     ASSERT_TRUE(pass);
3452
3453     // allocate memory
3454     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3455     ASSERT_VK_SUCCESS(err);
3456
3457     // Introduce validation failure, free memory before binding
3458     vkFreeMemory(m_device->device(), mem, NULL);
3459
3460     // Try to bind free memory that has been freed
3461     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3462     // This may very well return an error.
3463     (void)err;
3464
3465     m_errorMonitor->VerifyFound();
3466
3467     vkDestroyImage(m_device->device(), image, NULL);
3468 }
3469
3470 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3471     VkResult err;
3472     bool pass;
3473
3474     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3475
3476     ASSERT_NO_FATAL_FAILURE(InitState());
3477
3478     // Create an image object, allocate memory, destroy the object and then try
3479     // to bind it
3480     VkImage image;
3481     VkDeviceMemory mem;
3482     VkMemoryRequirements mem_reqs;
3483
3484     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3485     const int32_t tex_width = 32;
3486     const int32_t tex_height = 32;
3487
3488     VkImageCreateInfo image_create_info = {};
3489     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3490     image_create_info.pNext = NULL;
3491     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3492     image_create_info.format = tex_format;
3493     image_create_info.extent.width = tex_width;
3494     image_create_info.extent.height = tex_height;
3495     image_create_info.extent.depth = 1;
3496     image_create_info.mipLevels = 1;
3497     image_create_info.arrayLayers = 1;
3498     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3499     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3500     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3501     image_create_info.flags = 0;
3502
3503     VkMemoryAllocateInfo mem_alloc = {};
3504     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3505     mem_alloc.pNext = NULL;
3506     mem_alloc.allocationSize = 0;
3507     mem_alloc.memoryTypeIndex = 0;
3508
3509     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3510     ASSERT_VK_SUCCESS(err);
3511
3512     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3513
3514     mem_alloc.allocationSize = mem_reqs.size;
3515     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3516     ASSERT_TRUE(pass);
3517
3518     // Allocate memory
3519     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3520     ASSERT_VK_SUCCESS(err);
3521
3522     // Introduce validation failure, destroy Image object before binding
3523     vkDestroyImage(m_device->device(), image, NULL);
3524     ASSERT_VK_SUCCESS(err);
3525
3526     // Now Try to bind memory to this destroyed object
3527     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3528     // This may very well return an error.
3529     (void)err;
3530
3531     m_errorMonitor->VerifyFound();
3532
3533     vkFreeMemory(m_device->device(), mem, NULL);
3534 }
3535
3536 #endif // OBJ_TRACKER_TESTS
3537
3538 #if DRAW_STATE_TESTS
3539
3540 TEST_F(VkLayerTest, ImageSampleCounts) {
3541
3542     TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger "
3543                      "validation errors.");
3544     ASSERT_NO_FATAL_FAILURE(InitState());
3545
3546     VkMemoryPropertyFlags reqs = 0;
3547     VkImageCreateInfo image_create_info = {};
3548     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3549     image_create_info.pNext = NULL;
3550     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3551     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3552     image_create_info.extent.width = 256;
3553     image_create_info.extent.height = 256;
3554     image_create_info.extent.depth = 1;
3555     image_create_info.mipLevels = 1;
3556     image_create_info.arrayLayers = 1;
3557     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3558     image_create_info.flags = 0;
3559
3560     VkImageBlit blit_region = {};
3561     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3562     blit_region.srcSubresource.baseArrayLayer = 0;
3563     blit_region.srcSubresource.layerCount = 1;
3564     blit_region.srcSubresource.mipLevel = 0;
3565     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3566     blit_region.dstSubresource.baseArrayLayer = 0;
3567     blit_region.dstSubresource.layerCount = 1;
3568     blit_region.dstSubresource.mipLevel = 0;
3569
3570     // Create two images, the source with sampleCount = 2, and attempt to blit
3571     // between them
3572     {
3573         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3574         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3575         vk_testing::Image src_image;
3576         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3577         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3578         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3579         vk_testing::Image dst_image;
3580         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3581         m_commandBuffer->BeginCommandBuffer();
3582         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3583                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3584                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3585         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3586                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3587         m_errorMonitor->VerifyFound();
3588         m_commandBuffer->EndCommandBuffer();
3589     }
3590
3591     // Create two images, the dest with sampleCount = 4, and attempt to blit
3592     // between them
3593     {
3594         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3595         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3596         vk_testing::Image src_image;
3597         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3598         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3599         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3600         vk_testing::Image dst_image;
3601         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3602         m_commandBuffer->BeginCommandBuffer();
3603         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3604                                                                             "of VK_SAMPLE_COUNT_4_BIT but "
3605                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3606         vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3607                        dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3608         m_errorMonitor->VerifyFound();
3609         m_commandBuffer->EndCommandBuffer();
3610     }
3611
3612     VkBufferImageCopy copy_region = {};
3613     copy_region.bufferRowLength = 128;
3614     copy_region.bufferImageHeight = 128;
3615     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3616     copy_region.imageSubresource.layerCount = 1;
3617     copy_region.imageExtent.height = 64;
3618     copy_region.imageExtent.width = 64;
3619     copy_region.imageExtent.depth = 1;
3620
3621     // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3622     // buffer to image
3623     {
3624         vk_testing::Buffer src_buffer;
3625         VkMemoryPropertyFlags reqs = 0;
3626         src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3627         image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
3628         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3629         vk_testing::Image dst_image;
3630         dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3631         m_commandBuffer->BeginCommandBuffer();
3632         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3633                                                                             "of VK_SAMPLE_COUNT_8_BIT but "
3634                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3635         vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(),
3636                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
3637         m_errorMonitor->VerifyFound();
3638         m_commandBuffer->EndCommandBuffer();
3639     }
3640
3641     // Create dst buffer and src image with sampleCount = 2 and attempt to copy
3642     // image to buffer
3643     {
3644         vk_testing::Buffer dst_buffer;
3645         dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3646         image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3647         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3648         vk_testing::Image src_image;
3649         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3650         m_commandBuffer->BeginCommandBuffer();
3651         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3652                                                                             "of VK_SAMPLE_COUNT_2_BIT but "
3653                                                                             "must be VK_SAMPLE_COUNT_1_BIT");
3654         vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3655                                dst_buffer.handle(), 1, &copy_region);
3656         m_errorMonitor->VerifyFound();
3657         m_commandBuffer->EndCommandBuffer();
3658     }
3659 }
3660
3661 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
3662     VkResult err;
3663     bool pass;
3664
3665     TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
3666     ASSERT_NO_FATAL_FAILURE(InitState());
3667
3668     // If w/d/h granularity is 1, test is not meaningful
3669     // TODO: When virtual device limits are available, create a set of limits for this test that
3670     // will always have a granularity of > 1 for w, h, and d
3671     auto index = m_device->graphics_queue_node_index_;
3672     auto queue_family_properties = m_device->phy().queue_properties();
3673
3674     if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
3675         (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
3676         (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
3677         return;
3678     }
3679
3680     // Create two images of different types and try to copy between them
3681     VkImage srcImage;
3682     VkImage dstImage;
3683     VkDeviceMemory srcMem;
3684     VkDeviceMemory destMem;
3685     VkMemoryRequirements memReqs;
3686
3687     VkImageCreateInfo image_create_info = {};
3688     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3689     image_create_info.pNext = NULL;
3690     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3691     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3692     image_create_info.extent.width = 32;
3693     image_create_info.extent.height = 32;
3694     image_create_info.extent.depth = 1;
3695     image_create_info.mipLevels = 1;
3696     image_create_info.arrayLayers = 4;
3697     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3698     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3699     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3700     image_create_info.flags = 0;
3701
3702     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
3703     ASSERT_VK_SUCCESS(err);
3704
3705     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
3706     ASSERT_VK_SUCCESS(err);
3707
3708     // Allocate memory
3709     VkMemoryAllocateInfo memAlloc = {};
3710     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3711     memAlloc.pNext = NULL;
3712     memAlloc.allocationSize = 0;
3713     memAlloc.memoryTypeIndex = 0;
3714
3715     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
3716     memAlloc.allocationSize = memReqs.size;
3717     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3718     ASSERT_TRUE(pass);
3719     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
3720     ASSERT_VK_SUCCESS(err);
3721
3722     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
3723     memAlloc.allocationSize = memReqs.size;
3724     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3725     ASSERT_VK_SUCCESS(err);
3726     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
3727     ASSERT_VK_SUCCESS(err);
3728
3729     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
3730     ASSERT_VK_SUCCESS(err);
3731     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
3732     ASSERT_VK_SUCCESS(err);
3733
3734     BeginCommandBuffer();
3735     VkImageCopy copyRegion;
3736     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3737     copyRegion.srcSubresource.mipLevel = 0;
3738     copyRegion.srcSubresource.baseArrayLayer = 0;
3739     copyRegion.srcSubresource.layerCount = 1;
3740     copyRegion.srcOffset.x = 0;
3741     copyRegion.srcOffset.y = 0;
3742     copyRegion.srcOffset.z = 0;
3743     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3744     copyRegion.dstSubresource.mipLevel = 0;
3745     copyRegion.dstSubresource.baseArrayLayer = 0;
3746     copyRegion.dstSubresource.layerCount = 1;
3747     copyRegion.dstOffset.x = 0;
3748     copyRegion.dstOffset.y = 0;
3749     copyRegion.dstOffset.z = 0;
3750     copyRegion.extent.width = 1;
3751     copyRegion.extent.height = 1;
3752     copyRegion.extent.depth = 1;
3753
3754     // Introduce failure by setting srcOffset to a bad granularity value
3755     copyRegion.srcOffset.y = 3;
3756     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3757     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3758     m_errorMonitor->VerifyFound();
3759
3760     // Introduce failure by setting extent to a bad granularity value
3761     copyRegion.srcOffset.y = 0;
3762     copyRegion.extent.width = 3;
3763     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3764     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3765     m_errorMonitor->VerifyFound();
3766
3767     // Now do some buffer/image copies
3768     vk_testing::Buffer buffer;
3769     VkMemoryPropertyFlags reqs = 0;
3770     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3771     VkBufferImageCopy region = {};
3772     region.bufferOffset = 0;
3773     region.bufferRowLength = 3;
3774     region.bufferImageHeight = 128;
3775     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3776     region.imageSubresource.layerCount = 1;
3777     region.imageExtent.height = 16;
3778     region.imageExtent.width = 16;
3779     region.imageExtent.depth = 1;
3780     region.imageOffset.x = 0;
3781     region.imageOffset.y = 0;
3782     region.imageOffset.z = 0;
3783
3784     // Introduce failure by setting bufferRowLength to a bad granularity value
3785     region.bufferRowLength = 3;
3786     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3787     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3788                            &region);
3789     m_errorMonitor->VerifyFound();
3790     region.bufferRowLength = 128;
3791
3792     // Introduce failure by setting bufferOffset to a bad granularity value
3793     region.bufferOffset = 3;
3794     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3795     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3796                            &region);
3797     m_errorMonitor->VerifyFound();
3798     region.bufferOffset = 0;
3799
3800     // Introduce failure by setting bufferImageHeight to a bad granularity value
3801     region.bufferImageHeight = 3;
3802     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3803     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3804                            &region);
3805     m_errorMonitor->VerifyFound();
3806     region.bufferImageHeight = 128;
3807
3808     // Introduce failure by setting imageExtent to a bad granularity value
3809     region.imageExtent.width = 3;
3810     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3811     vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3812                            &region);
3813     m_errorMonitor->VerifyFound();
3814     region.imageExtent.width = 16;
3815
3816     // Introduce failure by setting imageOffset to a bad granularity value
3817     region.imageOffset.z = 3;
3818     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3819     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3820                            &region);
3821     m_errorMonitor->VerifyFound();
3822
3823     EndCommandBuffer();
3824
3825     vkDestroyImage(m_device->device(), srcImage, NULL);
3826     vkDestroyImage(m_device->device(), dstImage, NULL);
3827     vkFreeMemory(m_device->device(), srcMem, NULL);
3828     vkFreeMemory(m_device->device(), destMem, NULL);
3829 }
3830
3831 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
3832     TEST_DESCRIPTION("Submit command buffer created using one queue family and "
3833                      "attempt to submit them on a queue created in a different "
3834                      "queue family.");
3835
3836     ASSERT_NO_FATAL_FAILURE(InitState());
3837     // This test is meaningless unless we have multiple queue families
3838     auto queue_family_properties = m_device->phy().queue_properties();
3839     if (queue_family_properties.size() < 2) {
3840         return;
3841     }
3842     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue ");
3843     // Get safe index of another queue family
3844     uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
3845     ASSERT_NO_FATAL_FAILURE(InitState());
3846     // Create a second queue using a different queue family
3847     VkQueue other_queue;
3848     vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
3849
3850     // Record an empty cmd buffer
3851     VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3852     cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3853     vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
3854     vkEndCommandBuffer(m_commandBuffer->handle());
3855
3856     // And submit on the wrong queue
3857     VkSubmitInfo submit_info = {};
3858     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3859     submit_info.commandBufferCount = 1;
3860     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3861     vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
3862
3863     m_errorMonitor->VerifyFound();
3864 }
3865
3866 TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
3867     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
3868                      "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
3869                      "the command buffer has prior knowledge of that "
3870                      "attachment's layout.");
3871
3872     m_errorMonitor->ExpectSuccess();
3873
3874     ASSERT_NO_FATAL_FAILURE(InitState());
3875
3876     // A renderpass with one color attachment.
3877     VkAttachmentDescription attachment = {0,
3878                                           VK_FORMAT_R8G8B8A8_UNORM,
3879                                           VK_SAMPLE_COUNT_1_BIT,
3880                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3881                                           VK_ATTACHMENT_STORE_OP_STORE,
3882                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3883                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3884                                           VK_IMAGE_LAYOUT_UNDEFINED,
3885                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3886
3887     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3888
3889     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3890
3891     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3892
3893     VkRenderPass rp;
3894     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3895     ASSERT_VK_SUCCESS(err);
3896
3897     // A compatible framebuffer.
3898     VkImageObj image(m_device);
3899     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3900     ASSERT_TRUE(image.initialized());
3901
3902     VkImageViewCreateInfo ivci = {
3903         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3904         nullptr,
3905         0,
3906         image.handle(),
3907         VK_IMAGE_VIEW_TYPE_2D,
3908         VK_FORMAT_R8G8B8A8_UNORM,
3909         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3910          VK_COMPONENT_SWIZZLE_IDENTITY},
3911         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3912     };
3913     VkImageView view;
3914     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3915     ASSERT_VK_SUCCESS(err);
3916
3917     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3918     VkFramebuffer fb;
3919     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3920     ASSERT_VK_SUCCESS(err);
3921
3922     // Record a single command buffer which uses this renderpass twice. The
3923     // bug is triggered at the beginning of the second renderpass, when the
3924     // command buffer already has a layout recorded for the attachment.
3925     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3926     BeginCommandBuffer();
3927     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3928     vkCmdEndRenderPass(m_commandBuffer->handle());
3929     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3930
3931     m_errorMonitor->VerifyNotFound();
3932
3933     vkCmdEndRenderPass(m_commandBuffer->handle());
3934     EndCommandBuffer();
3935
3936     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3937     vkDestroyRenderPass(m_device->device(), rp, nullptr);
3938     vkDestroyImageView(m_device->device(), view, nullptr);
3939 }
3940
3941 TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
3942     TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
3943                      "command buffer, bind them together, then destroy "
3944                      "command pool and framebuffer and verify there are no "
3945                      "errors.");
3946
3947     m_errorMonitor->ExpectSuccess();
3948
3949     ASSERT_NO_FATAL_FAILURE(InitState());
3950
3951     // A renderpass with one color attachment.
3952     VkAttachmentDescription attachment = {0,
3953                                           VK_FORMAT_R8G8B8A8_UNORM,
3954                                           VK_SAMPLE_COUNT_1_BIT,
3955                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3956                                           VK_ATTACHMENT_STORE_OP_STORE,
3957                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3958                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3959                                           VK_IMAGE_LAYOUT_UNDEFINED,
3960                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3961
3962     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3963
3964     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3965
3966     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3967
3968     VkRenderPass rp;
3969     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3970     ASSERT_VK_SUCCESS(err);
3971
3972     // A compatible framebuffer.
3973     VkImageObj image(m_device);
3974     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3975     ASSERT_TRUE(image.initialized());
3976
3977     VkImageViewCreateInfo ivci = {
3978         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3979         nullptr,
3980         0,
3981         image.handle(),
3982         VK_IMAGE_VIEW_TYPE_2D,
3983         VK_FORMAT_R8G8B8A8_UNORM,
3984         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3985          VK_COMPONENT_SWIZZLE_IDENTITY},
3986         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3987     };
3988     VkImageView view;
3989     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3990     ASSERT_VK_SUCCESS(err);
3991
3992     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3993     VkFramebuffer fb;
3994     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3995     ASSERT_VK_SUCCESS(err);
3996
3997     // Explicitly create a command buffer to bind the FB to so that we can then
3998     //  destroy the command pool in order to implicitly free command buffer
3999     VkCommandPool command_pool;
4000     VkCommandPoolCreateInfo pool_create_info{};
4001     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4002     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4003     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4004     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4005
4006     VkCommandBuffer command_buffer;
4007     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4008     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4009     command_buffer_allocate_info.commandPool = command_pool;
4010     command_buffer_allocate_info.commandBufferCount = 1;
4011     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4012     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4013
4014     // Begin our cmd buffer with renderpass using our framebuffer
4015     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4016     VkCommandBufferBeginInfo begin_info{};
4017     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4018     vkBeginCommandBuffer(command_buffer, &begin_info);
4019
4020     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4021     vkCmdEndRenderPass(command_buffer);
4022     vkEndCommandBuffer(command_buffer);
4023     vkDestroyImageView(m_device->device(), view, nullptr);
4024     // Destroy command pool to implicitly free command buffer
4025     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4026     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4027     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4028     m_errorMonitor->VerifyNotFound();
4029 }
4030
4031 TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
4032     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
4033                      "transitions for the first subpass");
4034
4035     m_errorMonitor->ExpectSuccess();
4036
4037     ASSERT_NO_FATAL_FAILURE(InitState());
4038
4039     // A renderpass with one color attachment.
4040     VkAttachmentDescription attachment = {0,
4041                                           VK_FORMAT_R8G8B8A8_UNORM,
4042                                           VK_SAMPLE_COUNT_1_BIT,
4043                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4044                                           VK_ATTACHMENT_STORE_OP_STORE,
4045                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4046                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4047                                           VK_IMAGE_LAYOUT_UNDEFINED,
4048                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4049
4050     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4051
4052     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4053
4054     VkSubpassDependency dep = {0,
4055                                0,
4056                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4057                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4058                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4059                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4060                                VK_DEPENDENCY_BY_REGION_BIT};
4061
4062     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4063
4064     VkResult err;
4065     VkRenderPass rp;
4066     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4067     ASSERT_VK_SUCCESS(err);
4068
4069     // A compatible framebuffer.
4070     VkImageObj image(m_device);
4071     image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4072     ASSERT_TRUE(image.initialized());
4073
4074     VkImageViewCreateInfo ivci = {
4075         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4076         nullptr,
4077         0,
4078         image.handle(),
4079         VK_IMAGE_VIEW_TYPE_2D,
4080         VK_FORMAT_R8G8B8A8_UNORM,
4081         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
4082          VK_COMPONENT_SWIZZLE_IDENTITY},
4083         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
4084     };
4085     VkImageView view;
4086     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4087     ASSERT_VK_SUCCESS(err);
4088
4089     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4090     VkFramebuffer fb;
4091     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4092     ASSERT_VK_SUCCESS(err);
4093
4094     // Record a single command buffer which issues a pipeline barrier w/
4095     // image memory barrier for the attachment. This detects the previously
4096     // missing tracking of the subpass layout by throwing a validation error
4097     // if it doesn't occur.
4098     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4099     BeginCommandBuffer();
4100     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4101
4102     VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4103                                 nullptr,
4104                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4105                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4106                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4107                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4108                                 VK_QUEUE_FAMILY_IGNORED,
4109                                 VK_QUEUE_FAMILY_IGNORED,
4110                                 image.handle(),
4111                                 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
4112     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4113                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4114                          &imb);
4115
4116     vkCmdEndRenderPass(m_commandBuffer->handle());
4117     m_errorMonitor->VerifyNotFound();
4118     EndCommandBuffer();
4119
4120     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4121     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4122     vkDestroyImageView(m_device->device(), view, nullptr);
4123 }
4124
4125 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
4126     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4127     ASSERT_NO_FATAL_FAILURE(InitState());
4128
4129     // A renderpass with two subpasses, both writing the same attachment.
4130     VkAttachmentDescription attach[] = {
4131         { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
4132             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4133             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4134             VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4135         },
4136     };
4137     VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
4138     VkSubpassDescription subpasses[] = {
4139         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4140             1, &ref, nullptr, nullptr, 0, nullptr },
4141         { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4142             1, &ref, nullptr, nullptr, 0, nullptr },
4143     };
4144     VkSubpassDependency dep = {
4145         0, 1,
4146         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4147         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4148         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4149         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4150         VK_DEPENDENCY_BY_REGION_BIT
4151     };
4152     VkRenderPassCreateInfo rpci = {
4153         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
4154         0, 1, attach, 2, subpasses, 1, &dep
4155     };
4156     VkRenderPass rp;
4157     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4158     ASSERT_VK_SUCCESS(err);
4159
4160     VkImageObj image(m_device);
4161     image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
4162                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4163                          VK_IMAGE_TILING_OPTIMAL, 0);
4164     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4165
4166     VkFramebufferCreateInfo fbci = {
4167         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
4168         0, rp, 1, &imageView, 32, 32, 1
4169     };
4170     VkFramebuffer fb;
4171     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4172     ASSERT_VK_SUCCESS(err);
4173
4174     char const *vsSource =
4175         "#version 450\n"
4176         "void main() { gl_Position = vec4(1); }\n";
4177     char const *fsSource =
4178         "#version 450\n"
4179         "layout(location=0) out vec4 color;\n"
4180         "void main() { color = vec4(1); }\n";
4181
4182     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4183     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4184     VkPipelineObj pipe(m_device);
4185     pipe.AddColorAttachment();
4186     pipe.AddShader(&vs);
4187     pipe.AddShader(&fs);
4188     VkViewport view_port = {};
4189     m_viewports.push_back(view_port);
4190     pipe.SetViewport(m_viewports);
4191     VkRect2D rect = {};
4192     m_scissors.push_back(rect);
4193     pipe.SetScissor(m_scissors);
4194
4195     VkPipelineLayoutCreateInfo plci = {
4196         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
4197         0, 0, nullptr, 0, nullptr
4198     };
4199     VkPipelineLayout pl;
4200     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
4201     ASSERT_VK_SUCCESS(err);
4202     pipe.CreateVKPipeline(pl, rp);
4203
4204     BeginCommandBuffer();
4205
4206     VkRenderPassBeginInfo rpbi = {
4207         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
4208         rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
4209     };
4210
4211     // subtest 1: bind in the wrong subpass
4212     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4213     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4215                                          "built for subpass 0 but used in subpass 1");
4216     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4217     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4218     m_errorMonitor->VerifyFound();
4219
4220     vkCmdEndRenderPass(m_commandBuffer->handle());
4221
4222     // subtest 2: bind in correct subpass, then transition to next subpass
4223     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4224     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4225     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4226     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4227                                          "built for subpass 0 but used in subpass 1");
4228     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4229     m_errorMonitor->VerifyFound();
4230
4231     vkCmdEndRenderPass(m_commandBuffer->handle());
4232
4233     EndCommandBuffer();
4234
4235     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
4236     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4237     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4238 }
4239
4240 TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
4241     TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
4242                      "is used as a depth/stencil framebuffer attachment, the "
4243                      "aspectMask is ignored and both depth and stencil image "
4244                      "subresources are used.");
4245
4246     VkFormatProperties format_properties;
4247     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
4248     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
4249         return;
4250     }
4251
4252     m_errorMonitor->ExpectSuccess();
4253
4254     ASSERT_NO_FATAL_FAILURE(InitState());
4255
4256     VkAttachmentDescription attachment = {0,
4257                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
4258                                           VK_SAMPLE_COUNT_1_BIT,
4259                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4260                                           VK_ATTACHMENT_STORE_OP_STORE,
4261                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4262                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
4263                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4264                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4265
4266     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4267
4268     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
4269
4270     VkSubpassDependency dep = {0,
4271                                0,
4272                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4273                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4274                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4275                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4276                                VK_DEPENDENCY_BY_REGION_BIT};
4277
4278     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4279
4280     VkResult err;
4281     VkRenderPass rp;
4282     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4283     ASSERT_VK_SUCCESS(err);
4284
4285     VkImageObj image(m_device);
4286     image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
4287                          0x26, // usage
4288                          VK_IMAGE_TILING_OPTIMAL, 0);
4289     ASSERT_TRUE(image.initialized());
4290     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
4291
4292     VkImageViewCreateInfo ivci = {
4293         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4294         nullptr,
4295         0,
4296         image.handle(),
4297         VK_IMAGE_VIEW_TYPE_2D,
4298         VK_FORMAT_D32_SFLOAT_S8_UINT,
4299         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
4300         {0x2, 0, 1, 0, 1},
4301     };
4302     VkImageView view;
4303     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4304     ASSERT_VK_SUCCESS(err);
4305
4306     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4307     VkFramebuffer fb;
4308     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4309     ASSERT_VK_SUCCESS(err);
4310
4311     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4312     BeginCommandBuffer();
4313     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4314
4315     VkImageMemoryBarrier imb = {};
4316     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4317     imb.pNext = nullptr;
4318     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4319     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4320     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4321     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4322     imb.srcQueueFamilyIndex = 0;
4323     imb.dstQueueFamilyIndex = 0;
4324     imb.image = image.handle();
4325     imb.subresourceRange.aspectMask = 0x6;
4326     imb.subresourceRange.baseMipLevel = 0;
4327     imb.subresourceRange.levelCount = 0x1;
4328     imb.subresourceRange.baseArrayLayer = 0;
4329     imb.subresourceRange.layerCount = 0x1;
4330
4331     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4332                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4333                          &imb);
4334
4335     vkCmdEndRenderPass(m_commandBuffer->handle());
4336     EndCommandBuffer();
4337     QueueCommandBuffer(false);
4338     m_errorMonitor->VerifyNotFound();
4339
4340     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4341     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4342     vkDestroyImageView(m_device->device(), view, nullptr);
4343 }
4344
4345 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
4346     TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass"
4347                      "with extent outside of framebuffer");
4348     ASSERT_NO_FATAL_FAILURE(InitState());
4349     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4350
4351     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea "
4352                                                                         "not within the bound of the framebuffer.");
4353
4354     // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
4355     m_renderPassBeginInfo.renderArea.extent.width = 257;
4356     m_renderPassBeginInfo.renderArea.extent.height = 257;
4357     BeginCommandBuffer();
4358     m_errorMonitor->VerifyFound();
4359 }
4360
4361 TEST_F(VkLayerTest, DisabledIndependentBlend) {
4362     TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent "
4363                      "blend and then specifying different blend states for two "
4364                      "attachements");
4365     VkPhysicalDeviceFeatures features = {};
4366     features.independentBlend = VK_FALSE;
4367     ASSERT_NO_FATAL_FAILURE(InitState(&features));
4368
4369     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4370                                          "Invalid Pipeline CreateInfo: If independent blend feature not "
4371                                          "enabled, all elements of pAttachments must be identical");
4372
4373     VkDescriptorSetObj descriptorSet(m_device);
4374     descriptorSet.AppendDummy();
4375     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4376
4377     VkPipelineObj pipeline(m_device);
4378     VkRenderpassObj renderpass(m_device);
4379     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4380     pipeline.AddShader(&vs);
4381
4382     VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
4383     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4384     att_state1.blendEnable = VK_TRUE;
4385     att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4386     att_state2.blendEnable = VK_FALSE;
4387     pipeline.AddColorAttachment(0, &att_state1);
4388     pipeline.AddColorAttachment(1, &att_state2);
4389     pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle());
4390     m_errorMonitor->VerifyFound();
4391 }
4392
4393 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) {
4394     TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify "
4395                      "depth attachments in subpass");
4396     ASSERT_NO_FATAL_FAILURE(InitState());
4397
4398     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4399                                          "vkCreateRenderPass has no depth/stencil attachment, yet subpass");
4400
4401     // Create a renderPass with a single color attachment
4402     VkAttachmentReference attach = {};
4403     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4404     VkSubpassDescription subpass = {};
4405     VkRenderPassCreateInfo rpci = {};
4406     rpci.subpassCount = 1;
4407     rpci.pSubpasses = &subpass;
4408     rpci.attachmentCount = 1;
4409     VkAttachmentDescription attach_desc = {};
4410     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4411     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4412     rpci.pAttachments = &attach_desc;
4413     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4414     VkRenderPass rp;
4415     subpass.pDepthStencilAttachment = &attach;
4416     subpass.pColorAttachments = NULL;
4417     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4418     m_errorMonitor->VerifyFound();
4419 }
4420
4421 TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
4422     TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
4423                      "errors, when an attachment reference is "
4424                      "VK_ATTACHMENT_UNUSED");
4425
4426     m_errorMonitor->ExpectSuccess();
4427
4428     ASSERT_NO_FATAL_FAILURE(InitState());
4429
4430     // A renderpass with no attachments
4431     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4432
4433     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4434
4435     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
4436
4437     VkRenderPass rp;
4438     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4439     ASSERT_VK_SUCCESS(err);
4440
4441     // A compatible framebuffer.
4442     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
4443     VkFramebuffer fb;
4444     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4445     ASSERT_VK_SUCCESS(err);
4446
4447     // Record a command buffer which just begins and ends the renderpass. The
4448     // bug manifests in BeginRenderPass.
4449     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4450     BeginCommandBuffer();
4451     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4452     vkCmdEndRenderPass(m_commandBuffer->handle());
4453     m_errorMonitor->VerifyNotFound();
4454     EndCommandBuffer();
4455
4456     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4457     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4458 }
4459
4460 // This is a positive test. No errors are expected.
4461 TEST_F(VkLayerTest, StencilLoadOp) {
4462     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
4463                      "CLEAR. stencil[Load|Store]Op used to be ignored.");
4464     VkResult result = VK_SUCCESS;
4465     VkImageFormatProperties formatProps;
4466     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
4467                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
4468                                              &formatProps);
4469     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
4470         return;
4471     }
4472
4473     ASSERT_NO_FATAL_FAILURE(InitState());
4474     VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
4475     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
4476                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4477     VkAttachmentDescription att = {};
4478     VkAttachmentReference ref = {};
4479     att.format = depth_stencil_fmt;
4480     att.samples = VK_SAMPLE_COUNT_1_BIT;
4481     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
4482     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
4483     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
4484     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
4485     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4486     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4487
4488     VkClearValue clear;
4489     clear.depthStencil.depth = 1.0;
4490     clear.depthStencil.stencil = 0;
4491     ref.attachment = 0;
4492     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4493
4494     VkSubpassDescription subpass = {};
4495     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4496     subpass.flags = 0;
4497     subpass.inputAttachmentCount = 0;
4498     subpass.pInputAttachments = NULL;
4499     subpass.colorAttachmentCount = 0;
4500     subpass.pColorAttachments = NULL;
4501     subpass.pResolveAttachments = NULL;
4502     subpass.pDepthStencilAttachment = &ref;
4503     subpass.preserveAttachmentCount = 0;
4504     subpass.pPreserveAttachments = NULL;
4505
4506     VkRenderPass rp;
4507     VkRenderPassCreateInfo rp_info = {};
4508     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4509     rp_info.attachmentCount = 1;
4510     rp_info.pAttachments = &att;
4511     rp_info.subpassCount = 1;
4512     rp_info.pSubpasses = &subpass;
4513     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
4514     ASSERT_VK_SUCCESS(result);
4515
4516     VkImageView *depthView = m_depthStencil->BindInfo();
4517     VkFramebufferCreateInfo fb_info = {};
4518     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4519     fb_info.pNext = NULL;
4520     fb_info.renderPass = rp;
4521     fb_info.attachmentCount = 1;
4522     fb_info.pAttachments = depthView;
4523     fb_info.width = 100;
4524     fb_info.height = 100;
4525     fb_info.layers = 1;
4526     VkFramebuffer fb;
4527     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4528     ASSERT_VK_SUCCESS(result);
4529
4530     VkRenderPassBeginInfo rpbinfo = {};
4531     rpbinfo.clearValueCount = 1;
4532     rpbinfo.pClearValues = &clear;
4533     rpbinfo.pNext = NULL;
4534     rpbinfo.renderPass = rp;
4535     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4536     rpbinfo.renderArea.extent.width = 100;
4537     rpbinfo.renderArea.extent.height = 100;
4538     rpbinfo.renderArea.offset.x = 0;
4539     rpbinfo.renderArea.offset.y = 0;
4540     rpbinfo.framebuffer = fb;
4541
4542     VkFence fence = {};
4543     VkFenceCreateInfo fence_ci = {};
4544     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4545     fence_ci.pNext = nullptr;
4546     fence_ci.flags = 0;
4547     result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
4548     ASSERT_VK_SUCCESS(result);
4549
4550     m_commandBuffer->BeginCommandBuffer();
4551     m_commandBuffer->BeginRenderPass(rpbinfo);
4552     m_commandBuffer->EndRenderPass();
4553     m_commandBuffer->EndCommandBuffer();
4554     m_commandBuffer->QueueCommandBuffer(fence);
4555
4556     VkImageObj destImage(m_device);
4557     destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4558                    VK_IMAGE_TILING_OPTIMAL, 0);
4559     VkImageMemoryBarrier barrier = {};
4560     VkImageSubresourceRange range;
4561     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4562     barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4563     barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4564     barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4565     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4566     barrier.image = m_depthStencil->handle();
4567     range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4568     range.baseMipLevel = 0;
4569     range.levelCount = 1;
4570     range.baseArrayLayer = 0;
4571     range.layerCount = 1;
4572     barrier.subresourceRange = range;
4573     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4574     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
4575     cmdbuf.BeginCommandBuffer();
4576     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4577                            &barrier);
4578     barrier.srcAccessMask = 0;
4579     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4580     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4581     barrier.image = destImage.handle();
4582     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4583     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4584                            &barrier);
4585     VkImageCopy cregion;
4586     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4587     cregion.srcSubresource.mipLevel = 0;
4588     cregion.srcSubresource.baseArrayLayer = 0;
4589     cregion.srcSubresource.layerCount = 1;
4590     cregion.srcOffset.x = 0;
4591     cregion.srcOffset.y = 0;
4592     cregion.srcOffset.z = 0;
4593     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4594     cregion.dstSubresource.mipLevel = 0;
4595     cregion.dstSubresource.baseArrayLayer = 0;
4596     cregion.dstSubresource.layerCount = 1;
4597     cregion.dstOffset.x = 0;
4598     cregion.dstOffset.y = 0;
4599     cregion.dstOffset.z = 0;
4600     cregion.extent.width = 100;
4601     cregion.extent.height = 100;
4602     cregion.extent.depth = 1;
4603     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
4604                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
4605     cmdbuf.EndCommandBuffer();
4606
4607     VkSubmitInfo submit_info;
4608     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4609     submit_info.pNext = NULL;
4610     submit_info.waitSemaphoreCount = 0;
4611     submit_info.pWaitSemaphores = NULL;
4612     submit_info.pWaitDstStageMask = NULL;
4613     submit_info.commandBufferCount = 1;
4614     submit_info.pCommandBuffers = &cmdbuf.handle();
4615     submit_info.signalSemaphoreCount = 0;
4616     submit_info.pSignalSemaphores = NULL;
4617
4618     m_errorMonitor->ExpectSuccess();
4619     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4620     m_errorMonitor->VerifyNotFound();
4621
4622     vkQueueWaitIdle(m_device->m_queue);
4623     vkDestroyFence(m_device->device(), fence, nullptr);
4624     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4625     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4626 }
4627
4628 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
4629     TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
4630                      "attachment reference of VK_ATTACHMENT_UNUSED");
4631
4632     ASSERT_NO_FATAL_FAILURE(InitState());
4633     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4634
4635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED");
4636
4637     VkAttachmentReference color_attach = {};
4638     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4639     color_attach.attachment = 0;
4640     uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
4641     VkSubpassDescription subpass = {};
4642     subpass.colorAttachmentCount = 1;
4643     subpass.pColorAttachments = &color_attach;
4644     subpass.preserveAttachmentCount = 1;
4645     subpass.pPreserveAttachments = &preserve_attachment;
4646
4647     VkRenderPassCreateInfo rpci = {};
4648     rpci.subpassCount = 1;
4649     rpci.pSubpasses = &subpass;
4650     rpci.attachmentCount = 1;
4651     VkAttachmentDescription attach_desc = {};
4652     attach_desc.format = VK_FORMAT_UNDEFINED;
4653     rpci.pAttachments = &attach_desc;
4654     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4655     VkRenderPass rp;
4656     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4657
4658     m_errorMonitor->VerifyFound();
4659
4660     if (result == VK_SUCCESS) {
4661         vkDestroyRenderPass(m_device->device(), rp, NULL);
4662     }
4663 }
4664
4665 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
4666     TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
4667                      "when the source of a subpass multisample resolve "
4668                      "does not have multiple samples.");
4669
4670     ASSERT_NO_FATAL_FAILURE(InitState());
4671
4672     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4673                                          "Subpass 0 requests multisample resolve from attachment 0 which has "
4674                                          "VK_SAMPLE_COUNT_1_BIT");
4675
4676     VkAttachmentDescription attachments[] = {
4677         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4678          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4679          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4680         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4681          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4682          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4683     };
4684
4685     VkAttachmentReference color = {
4686         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4687     };
4688
4689     VkAttachmentReference resolve = {
4690         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4691     };
4692
4693     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4694
4695     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4696
4697     VkRenderPass rp;
4698     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4699
4700     m_errorMonitor->VerifyFound();
4701
4702     if (err == VK_SUCCESS)
4703         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4704 }
4705
4706 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
4707     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4708                      "when a subpass multisample resolve operation is "
4709                      "requested, and the destination of that resolve has "
4710                      "multiple samples.");
4711
4712     ASSERT_NO_FATAL_FAILURE(InitState());
4713
4714     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4715                                          "Subpass 0 requests multisample resolve into attachment 1, which "
4716                                          "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
4717
4718     VkAttachmentDescription attachments[] = {
4719         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4720          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4721          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4722         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4723          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4724          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4725     };
4726
4727     VkAttachmentReference color = {
4728         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4729     };
4730
4731     VkAttachmentReference resolve = {
4732         1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4733     };
4734
4735     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4736
4737     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4738
4739     VkRenderPass rp;
4740     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4741
4742     m_errorMonitor->VerifyFound();
4743
4744     if (err == VK_SUCCESS)
4745         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4746 }
4747
4748 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
4749     TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4750                      "when the color and depth attachments used by a subpass "
4751                      "have inconsistent sample counts");
4752
4753     ASSERT_NO_FATAL_FAILURE(InitState());
4754
4755     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4756                                          "Subpass 0 attempts to render to attachments with inconsistent sample counts");
4757
4758     VkAttachmentDescription attachments[] = {
4759         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4760          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4761          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4762         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4763          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4764          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4765     };
4766
4767     VkAttachmentReference color[] = {
4768         {
4769             0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4770         },
4771         {
4772             1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4773         },
4774     };
4775
4776     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr};
4777
4778     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4779
4780     VkRenderPass rp;
4781     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4782
4783     m_errorMonitor->VerifyFound();
4784
4785     if (err == VK_SUCCESS)
4786         vkDestroyRenderPass(m_device->device(), rp, nullptr);
4787 }
4788
4789 TEST_F(VkLayerTest, FramebufferCreateErrors) {
4790     TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
4791                      " 1. Mismatch between fb & renderPass attachmentCount\n"
4792                      " 2. Use a color image as depthStencil attachment\n"
4793                      " 3. Mismatch fb & renderPass attachment formats\n"
4794                      " 4. Mismatch fb & renderPass attachment #samples\n"
4795                      " 5. FB attachment w/ non-1 mip-levels\n"
4796                      " 6. FB attachment where dimensions don't match\n"
4797                      " 7. FB attachment w/o identity swizzle\n"
4798                      " 8. FB dimensions exceed physical device limits\n");
4799
4800     ASSERT_NO_FATAL_FAILURE(InitState());
4801     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4802
4803     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4804                                          "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
4805                                          "does not match attachmentCount of 1 of ");
4806
4807     // Create a renderPass with a single color attachment
4808     VkAttachmentReference attach = {};
4809     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4810     VkSubpassDescription subpass = {};
4811     subpass.pColorAttachments = &attach;
4812     VkRenderPassCreateInfo rpci = {};
4813     rpci.subpassCount = 1;
4814     rpci.pSubpasses = &subpass;
4815     rpci.attachmentCount = 1;
4816     VkAttachmentDescription attach_desc = {};
4817     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4818     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4819     rpci.pAttachments = &attach_desc;
4820     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4821     VkRenderPass rp;
4822     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4823     ASSERT_VK_SUCCESS(err);
4824
4825     VkImageView ivs[2];
4826     ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4827     ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4828     VkFramebufferCreateInfo fb_info = {};
4829     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4830     fb_info.pNext = NULL;
4831     fb_info.renderPass = rp;
4832     // Set mis-matching attachmentCount
4833     fb_info.attachmentCount = 2;
4834     fb_info.pAttachments = ivs;
4835     fb_info.width = 100;
4836     fb_info.height = 100;
4837     fb_info.layers = 1;
4838
4839     VkFramebuffer fb;
4840     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4841
4842     m_errorMonitor->VerifyFound();
4843     if (err == VK_SUCCESS) {
4844         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4845     }
4846     vkDestroyRenderPass(m_device->device(), rp, NULL);
4847
4848     // Create a renderPass with a depth-stencil attachment created with
4849     // IMAGE_USAGE_COLOR_ATTACHMENT
4850     // Add our color attachment to pDepthStencilAttachment
4851     subpass.pDepthStencilAttachment = &attach;
4852     subpass.pColorAttachments = NULL;
4853     VkRenderPass rp_ds;
4854     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
4855     ASSERT_VK_SUCCESS(err);
4856     // Set correct attachment count, but attachment has COLOR usage bit set
4857     fb_info.attachmentCount = 1;
4858     fb_info.renderPass = rp_ds;
4859
4860     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags ");
4861     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4862
4863     m_errorMonitor->VerifyFound();
4864     if (err == VK_SUCCESS) {
4865         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4866     }
4867     vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
4868
4869     // Create new renderpass with alternate attachment format from fb
4870     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
4871     subpass.pDepthStencilAttachment = NULL;
4872     subpass.pColorAttachments = &attach;
4873     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4874     ASSERT_VK_SUCCESS(err);
4875
4876     // Cause error due to mis-matched formats between rp & fb
4877     //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
4878     fb_info.renderPass = rp;
4879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4880                                          " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
4881     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4882
4883     m_errorMonitor->VerifyFound();
4884     if (err == VK_SUCCESS) {
4885         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4886     }
4887     vkDestroyRenderPass(m_device->device(), rp, NULL);
4888
4889     // Create new renderpass with alternate sample count from fb
4890     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4891     attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
4892     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4893     ASSERT_VK_SUCCESS(err);
4894
4895     // Cause error due to mis-matched sample count between rp & fb
4896     fb_info.renderPass = rp;
4897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples "
4898                                                                         "that do not match the "
4899                                                                         "VK_SAMPLE_COUNT_4_BIT ");
4900     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4901
4902     m_errorMonitor->VerifyFound();
4903     if (err == VK_SUCCESS) {
4904         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4905     }
4906
4907     vkDestroyRenderPass(m_device->device(), rp, NULL);
4908
4909     // Create a custom imageView with non-1 mip levels
4910     VkImageObj image(m_device);
4911     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4912     ASSERT_TRUE(image.initialized());
4913
4914     VkImageView view;
4915     VkImageViewCreateInfo ivci = {};
4916     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4917     ivci.image = image.handle();
4918     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4919     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4920     ivci.subresourceRange.layerCount = 1;
4921     ivci.subresourceRange.baseMipLevel = 0;
4922     // Set level count 2 (only 1 is allowed for FB attachment)
4923     ivci.subresourceRange.levelCount = 2;
4924     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4925     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4926     ASSERT_VK_SUCCESS(err);
4927     // Re-create renderpass to have matching sample count
4928     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4929     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4930     ASSERT_VK_SUCCESS(err);
4931
4932     fb_info.renderPass = rp;
4933     fb_info.pAttachments = &view;
4934     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only ");
4935     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4936
4937     m_errorMonitor->VerifyFound();
4938     if (err == VK_SUCCESS) {
4939         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4940     }
4941     vkDestroyImageView(m_device->device(), view, NULL);
4942     // Update view to original color buffer and grow FB dimensions too big
4943     fb_info.pAttachments = ivs;
4944     fb_info.height = 1024;
4945     fb_info.width = 1024;
4946     fb_info.layers = 2;
4947     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at "
4948                                                                         "least as large. ");
4949     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4950
4951     m_errorMonitor->VerifyFound();
4952     if (err == VK_SUCCESS) {
4953         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4954     }
4955     // Create view attachment with non-identity swizzle
4956     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4957     ivci.image = image.handle();
4958     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4959     ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4960     ivci.subresourceRange.layerCount = 1;
4961     ivci.subresourceRange.baseMipLevel = 0;
4962     ivci.subresourceRange.levelCount = 1;
4963     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4964     ivci.components.r = VK_COMPONENT_SWIZZLE_G;
4965     ivci.components.g = VK_COMPONENT_SWIZZLE_R;
4966     ivci.components.b = VK_COMPONENT_SWIZZLE_A;
4967     ivci.components.a = VK_COMPONENT_SWIZZLE_B;
4968     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4969     ASSERT_VK_SUCCESS(err);
4970
4971     fb_info.pAttachments = &view;
4972     fb_info.height = 100;
4973     fb_info.width = 100;
4974     fb_info.layers = 1;
4975     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All "
4976                                                                         "framebuffer attachments must have "
4977                                                                         "been created with the identity "
4978                                                                         "swizzle. ");
4979     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4980
4981     m_errorMonitor->VerifyFound();
4982     if (err == VK_SUCCESS) {
4983         vkDestroyFramebuffer(m_device->device(), fb, NULL);
4984     }
4985     vkDestroyImageView(m_device->device(), view, NULL);
4986     // Request fb that exceeds max dimensions
4987     // reset attachment to color attachment
4988     fb_info.pAttachments = ivs;
4989     fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
4990     fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
4991     fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
4992     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo "
4993                                                                         "dimensions exceed physical device "
4994                                                                         "limits. ");
4995     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4996
4997     m_errorMonitor->VerifyFound();
4998     if (err == VK_SUCCESS) {
4999         vkDestroyFramebuffer(m_device->device(), fb, NULL);
5000     }
5001
5002     vkDestroyRenderPass(m_device->device(), rp, NULL);
5003 }
5004
5005 // This is a positive test.  No errors should be generated.
5006 TEST_F(VkLayerTest, WaitEventThenSet) {
5007     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
5008
5009     m_errorMonitor->ExpectSuccess();
5010     ASSERT_NO_FATAL_FAILURE(InitState());
5011
5012     VkEvent event;
5013     VkEventCreateInfo event_create_info{};
5014     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5015     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5016
5017     VkCommandPool command_pool;
5018     VkCommandPoolCreateInfo pool_create_info{};
5019     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5020     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5021     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5022     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5023
5024     VkCommandBuffer command_buffer;
5025     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5026     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5027     command_buffer_allocate_info.commandPool = command_pool;
5028     command_buffer_allocate_info.commandBufferCount = 1;
5029     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5030     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5031
5032     VkQueue queue = VK_NULL_HANDLE;
5033     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5034
5035     {
5036         VkCommandBufferBeginInfo begin_info{};
5037         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5038         vkBeginCommandBuffer(command_buffer, &begin_info);
5039
5040         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
5041                         nullptr, 0, nullptr);
5042         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5043         vkEndCommandBuffer(command_buffer);
5044     }
5045     {
5046         VkSubmitInfo submit_info{};
5047         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5048         submit_info.commandBufferCount = 1;
5049         submit_info.pCommandBuffers = &command_buffer;
5050         submit_info.signalSemaphoreCount = 0;
5051         submit_info.pSignalSemaphores = nullptr;
5052         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5053     }
5054     { vkSetEvent(m_device->device(), event); }
5055
5056     vkQueueWaitIdle(queue);
5057
5058     vkDestroyEvent(m_device->device(), event, nullptr);
5059     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5060     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5061
5062     m_errorMonitor->VerifyNotFound();
5063 }
5064 // This is a positive test.  No errors should be generated.
5065 TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
5066     TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
5067
5068     ASSERT_NO_FATAL_FAILURE(InitState());
5069     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5070         return;
5071
5072     m_errorMonitor->ExpectSuccess();
5073
5074     VkQueryPool query_pool;
5075     VkQueryPoolCreateInfo query_pool_create_info{};
5076     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5077     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5078     query_pool_create_info.queryCount = 1;
5079     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5080
5081     VkCommandPool command_pool;
5082     VkCommandPoolCreateInfo pool_create_info{};
5083     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5084     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5085     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5086     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5087
5088     VkCommandBuffer command_buffer;
5089     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5090     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5091     command_buffer_allocate_info.commandPool = command_pool;
5092     command_buffer_allocate_info.commandBufferCount = 1;
5093     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5094     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5095
5096     VkCommandBuffer secondary_command_buffer;
5097     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5098     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
5099
5100     VkQueue queue = VK_NULL_HANDLE;
5101     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5102
5103     uint32_t qfi = 0;
5104     VkBufferCreateInfo buff_create_info = {};
5105     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5106     buff_create_info.size = 1024;
5107     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5108     buff_create_info.queueFamilyIndexCount = 1;
5109     buff_create_info.pQueueFamilyIndices = &qfi;
5110
5111     VkResult err;
5112     VkBuffer buffer;
5113     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5114     ASSERT_VK_SUCCESS(err);
5115     VkMemoryAllocateInfo mem_alloc = {};
5116     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5117     mem_alloc.pNext = NULL;
5118     mem_alloc.allocationSize = 1024;
5119     mem_alloc.memoryTypeIndex = 0;
5120
5121     VkMemoryRequirements memReqs;
5122     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5123     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5124     if (!pass) {
5125         vkDestroyBuffer(m_device->device(), buffer, NULL);
5126         return;
5127     }
5128
5129     VkDeviceMemory mem;
5130     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5131     ASSERT_VK_SUCCESS(err);
5132     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5133     ASSERT_VK_SUCCESS(err);
5134
5135     VkCommandBufferInheritanceInfo hinfo = {};
5136     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5137     hinfo.renderPass = VK_NULL_HANDLE;
5138     hinfo.subpass = 0;
5139     hinfo.framebuffer = VK_NULL_HANDLE;
5140     hinfo.occlusionQueryEnable = VK_FALSE;
5141     hinfo.queryFlags = 0;
5142     hinfo.pipelineStatistics = 0;
5143
5144     {
5145         VkCommandBufferBeginInfo begin_info{};
5146         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5147         begin_info.pInheritanceInfo = &hinfo;
5148         vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
5149
5150         vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
5151         vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5152
5153         vkEndCommandBuffer(secondary_command_buffer);
5154
5155         begin_info.pInheritanceInfo = nullptr;
5156         vkBeginCommandBuffer(command_buffer, &begin_info);
5157
5158         vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
5159         vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
5160
5161         vkEndCommandBuffer(command_buffer);
5162     }
5163     {
5164         VkSubmitInfo submit_info{};
5165         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5166         submit_info.commandBufferCount = 1;
5167         submit_info.pCommandBuffers = &command_buffer;
5168         submit_info.signalSemaphoreCount = 0;
5169         submit_info.pSignalSemaphores = nullptr;
5170         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5171     }
5172
5173     vkQueueWaitIdle(queue);
5174
5175     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5176     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5177     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
5178     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5179     vkDestroyBuffer(m_device->device(), buffer, NULL);
5180     vkFreeMemory(m_device->device(), mem, NULL);
5181
5182     m_errorMonitor->VerifyNotFound();
5183 }
5184
5185 // This is a positive test.  No errors should be generated.
5186 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
5187     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
5188
5189     ASSERT_NO_FATAL_FAILURE(InitState());
5190     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5191         return;
5192
5193     m_errorMonitor->ExpectSuccess();
5194
5195     VkQueryPool query_pool;
5196     VkQueryPoolCreateInfo query_pool_create_info{};
5197     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5198     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5199     query_pool_create_info.queryCount = 1;
5200     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5201
5202     VkCommandPool command_pool;
5203     VkCommandPoolCreateInfo pool_create_info{};
5204     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5205     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5206     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5207     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5208
5209     VkCommandBuffer command_buffer[2];
5210     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5211     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5212     command_buffer_allocate_info.commandPool = command_pool;
5213     command_buffer_allocate_info.commandBufferCount = 2;
5214     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5215     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5216
5217     VkQueue queue = VK_NULL_HANDLE;
5218     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5219
5220     uint32_t qfi = 0;
5221     VkBufferCreateInfo buff_create_info = {};
5222     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5223     buff_create_info.size = 1024;
5224     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5225     buff_create_info.queueFamilyIndexCount = 1;
5226     buff_create_info.pQueueFamilyIndices = &qfi;
5227
5228     VkResult err;
5229     VkBuffer buffer;
5230     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5231     ASSERT_VK_SUCCESS(err);
5232     VkMemoryAllocateInfo mem_alloc = {};
5233     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5234     mem_alloc.pNext = NULL;
5235     mem_alloc.allocationSize = 1024;
5236     mem_alloc.memoryTypeIndex = 0;
5237
5238     VkMemoryRequirements memReqs;
5239     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5240     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5241     if (!pass) {
5242         vkDestroyBuffer(m_device->device(), buffer, NULL);
5243         return;
5244     }
5245
5246     VkDeviceMemory mem;
5247     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5248     ASSERT_VK_SUCCESS(err);
5249     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5250     ASSERT_VK_SUCCESS(err);
5251
5252     {
5253         VkCommandBufferBeginInfo begin_info{};
5254         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5255         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5256
5257         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
5258         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5259
5260         vkEndCommandBuffer(command_buffer[0]);
5261
5262         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5263
5264         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
5265
5266         vkEndCommandBuffer(command_buffer[1]);
5267     }
5268     {
5269         VkSubmitInfo submit_info{};
5270         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5271         submit_info.commandBufferCount = 2;
5272         submit_info.pCommandBuffers = command_buffer;
5273         submit_info.signalSemaphoreCount = 0;
5274         submit_info.pSignalSemaphores = nullptr;
5275         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5276     }
5277
5278     vkQueueWaitIdle(queue);
5279
5280     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5281     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
5282     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5283     vkDestroyBuffer(m_device->device(), buffer, NULL);
5284     vkFreeMemory(m_device->device(), mem, NULL);
5285
5286     m_errorMonitor->VerifyNotFound();
5287 }
5288
5289 TEST_F(VkLayerTest, ResetEventThenSet) {
5290     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
5291
5292     m_errorMonitor->ExpectSuccess();
5293
5294     ASSERT_NO_FATAL_FAILURE(InitState());
5295     VkEvent event;
5296     VkEventCreateInfo event_create_info{};
5297     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5298     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5299
5300     VkCommandPool command_pool;
5301     VkCommandPoolCreateInfo pool_create_info{};
5302     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5303     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5304     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5305     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5306
5307     VkCommandBuffer command_buffer;
5308     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5309     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5310     command_buffer_allocate_info.commandPool = command_pool;
5311     command_buffer_allocate_info.commandBufferCount = 1;
5312     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5313     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5314
5315     VkQueue queue = VK_NULL_HANDLE;
5316     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5317
5318     {
5319         VkCommandBufferBeginInfo begin_info{};
5320         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5321         vkBeginCommandBuffer(command_buffer, &begin_info);
5322
5323         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5324         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
5325                         nullptr, 0, nullptr, 0, nullptr);
5326         vkEndCommandBuffer(command_buffer);
5327     }
5328     {
5329         VkSubmitInfo submit_info{};
5330         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5331         submit_info.commandBufferCount = 1;
5332         submit_info.pCommandBuffers = &command_buffer;
5333         submit_info.signalSemaphoreCount = 0;
5334         submit_info.pSignalSemaphores = nullptr;
5335         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5336     }
5337     {
5338         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
5339                                                                             "command buffer.");
5340         vkSetEvent(m_device->device(), event);
5341         m_errorMonitor->VerifyFound();
5342     }
5343
5344     vkQueueWaitIdle(queue);
5345
5346     vkDestroyEvent(m_device->device(), event, nullptr);
5347     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5348     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5349 }
5350
5351 // This is a positive test.  No errors should be generated.
5352 TEST_F(VkLayerTest, TwoFencesThreeFrames) {
5353     TEST_DESCRIPTION("Two command buffers with two separate fences are each "
5354                      "run through a Submit & WaitForFences cycle 3 times. This "
5355                      "previously revealed a bug so running this positive test "
5356                      "to prevent a regression.");
5357     m_errorMonitor->ExpectSuccess();
5358
5359     ASSERT_NO_FATAL_FAILURE(InitState());
5360     VkQueue queue = VK_NULL_HANDLE;
5361     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5362
5363     static const uint32_t NUM_OBJECTS = 2;
5364     static const uint32_t NUM_FRAMES = 3;
5365     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
5366     VkFence fences[NUM_OBJECTS] = {};
5367
5368     VkCommandPool cmd_pool;
5369     VkCommandPoolCreateInfo cmd_pool_ci = {};
5370     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5371     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
5372     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5373     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
5374     ASSERT_VK_SUCCESS(err);
5375
5376     VkCommandBufferAllocateInfo cmd_buf_info = {};
5377     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5378     cmd_buf_info.commandPool = cmd_pool;
5379     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5380     cmd_buf_info.commandBufferCount = 1;
5381
5382     VkFenceCreateInfo fence_ci = {};
5383     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5384     fence_ci.pNext = nullptr;
5385     fence_ci.flags = 0;
5386
5387     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5388         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
5389         ASSERT_VK_SUCCESS(err);
5390         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
5391         ASSERT_VK_SUCCESS(err);
5392     }
5393
5394     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
5395         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
5396             // Create empty cmd buffer
5397             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
5398             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5399
5400             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
5401             ASSERT_VK_SUCCESS(err);
5402             err = vkEndCommandBuffer(cmd_buffers[obj]);
5403             ASSERT_VK_SUCCESS(err);
5404
5405             VkSubmitInfo submit_info = {};
5406             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5407             submit_info.commandBufferCount = 1;
5408             submit_info.pCommandBuffers = &cmd_buffers[obj];
5409             // Submit cmd buffer and wait for fence
5410             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
5411             ASSERT_VK_SUCCESS(err);
5412             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
5413             ASSERT_VK_SUCCESS(err);
5414             err = vkResetFences(m_device->device(), 1, &fences[obj]);
5415             ASSERT_VK_SUCCESS(err);
5416         }
5417     }
5418     m_errorMonitor->VerifyNotFound();
5419     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
5420     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5421         vkDestroyFence(m_device->device(), fences[i], nullptr);
5422     }
5423 }
5424 // This is a positive test.  No errors should be generated.
5425 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
5426
5427     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5428                      "submitted on separate queues followed by a QueueWaitIdle.");
5429
5430     ASSERT_NO_FATAL_FAILURE(InitState());
5431     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5432         return;
5433
5434     m_errorMonitor->ExpectSuccess();
5435
5436     VkSemaphore semaphore;
5437     VkSemaphoreCreateInfo semaphore_create_info{};
5438     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5439     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5440
5441     VkCommandPool command_pool;
5442     VkCommandPoolCreateInfo pool_create_info{};
5443     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5444     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5445     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5446     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5447
5448     VkCommandBuffer command_buffer[2];
5449     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5450     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5451     command_buffer_allocate_info.commandPool = command_pool;
5452     command_buffer_allocate_info.commandBufferCount = 2;
5453     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5454     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5455
5456     VkQueue queue = VK_NULL_HANDLE;
5457     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5458
5459     {
5460         VkCommandBufferBeginInfo begin_info{};
5461         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5462         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5463
5464         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5465                              nullptr, 0, nullptr, 0, nullptr);
5466
5467         VkViewport viewport{};
5468         viewport.maxDepth = 1.0f;
5469         viewport.minDepth = 0.0f;
5470         viewport.width = 512;
5471         viewport.height = 512;
5472         viewport.x = 0;
5473         viewport.y = 0;
5474         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5475         vkEndCommandBuffer(command_buffer[0]);
5476     }
5477     {
5478         VkCommandBufferBeginInfo begin_info{};
5479         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5480         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5481
5482         VkViewport viewport{};
5483         viewport.maxDepth = 1.0f;
5484         viewport.minDepth = 0.0f;
5485         viewport.width = 512;
5486         viewport.height = 512;
5487         viewport.x = 0;
5488         viewport.y = 0;
5489         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5490         vkEndCommandBuffer(command_buffer[1]);
5491     }
5492     {
5493         VkSubmitInfo submit_info{};
5494         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5495         submit_info.commandBufferCount = 1;
5496         submit_info.pCommandBuffers = &command_buffer[0];
5497         submit_info.signalSemaphoreCount = 1;
5498         submit_info.pSignalSemaphores = &semaphore;
5499         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5500     }
5501     {
5502         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5503         VkSubmitInfo submit_info{};
5504         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5505         submit_info.commandBufferCount = 1;
5506         submit_info.pCommandBuffers = &command_buffer[1];
5507         submit_info.waitSemaphoreCount = 1;
5508         submit_info.pWaitSemaphores = &semaphore;
5509         submit_info.pWaitDstStageMask = flags;
5510         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5511     }
5512
5513     vkQueueWaitIdle(m_device->m_queue);
5514
5515     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5516     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5517     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5518
5519     m_errorMonitor->VerifyNotFound();
5520 }
5521
5522 // This is a positive test.  No errors should be generated.
5523 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
5524
5525     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5526                      "submitted on separate queues, the second having a fence"
5527                      "followed by a QueueWaitIdle.");
5528
5529     ASSERT_NO_FATAL_FAILURE(InitState());
5530     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5531         return;
5532
5533     m_errorMonitor->ExpectSuccess();
5534
5535     VkFence fence;
5536     VkFenceCreateInfo fence_create_info{};
5537     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5538     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5539
5540     VkSemaphore semaphore;
5541     VkSemaphoreCreateInfo semaphore_create_info{};
5542     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5543     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5544
5545     VkCommandPool command_pool;
5546     VkCommandPoolCreateInfo pool_create_info{};
5547     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5548     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5549     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5550     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5551
5552     VkCommandBuffer command_buffer[2];
5553     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5554     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5555     command_buffer_allocate_info.commandPool = command_pool;
5556     command_buffer_allocate_info.commandBufferCount = 2;
5557     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5558     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5559
5560     VkQueue queue = VK_NULL_HANDLE;
5561     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5562
5563     {
5564         VkCommandBufferBeginInfo begin_info{};
5565         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5566         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5567
5568         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5569                              nullptr, 0, nullptr, 0, nullptr);
5570
5571         VkViewport viewport{};
5572         viewport.maxDepth = 1.0f;
5573         viewport.minDepth = 0.0f;
5574         viewport.width = 512;
5575         viewport.height = 512;
5576         viewport.x = 0;
5577         viewport.y = 0;
5578         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5579         vkEndCommandBuffer(command_buffer[0]);
5580     }
5581     {
5582         VkCommandBufferBeginInfo begin_info{};
5583         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5584         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5585
5586         VkViewport viewport{};
5587         viewport.maxDepth = 1.0f;
5588         viewport.minDepth = 0.0f;
5589         viewport.width = 512;
5590         viewport.height = 512;
5591         viewport.x = 0;
5592         viewport.y = 0;
5593         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5594         vkEndCommandBuffer(command_buffer[1]);
5595     }
5596     {
5597         VkSubmitInfo submit_info{};
5598         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5599         submit_info.commandBufferCount = 1;
5600         submit_info.pCommandBuffers = &command_buffer[0];
5601         submit_info.signalSemaphoreCount = 1;
5602         submit_info.pSignalSemaphores = &semaphore;
5603         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5604     }
5605     {
5606         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5607         VkSubmitInfo submit_info{};
5608         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5609         submit_info.commandBufferCount = 1;
5610         submit_info.pCommandBuffers = &command_buffer[1];
5611         submit_info.waitSemaphoreCount = 1;
5612         submit_info.pWaitSemaphores = &semaphore;
5613         submit_info.pWaitDstStageMask = flags;
5614         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5615     }
5616
5617     vkQueueWaitIdle(m_device->m_queue);
5618
5619     vkDestroyFence(m_device->device(), fence, nullptr);
5620     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5621     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5622     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5623
5624     m_errorMonitor->VerifyNotFound();
5625 }
5626
5627 // This is a positive test.  No errors should be generated.
5628 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
5629
5630     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5631                      "submitted on separate queues, the second having a fence"
5632                      "followed by two consecutive WaitForFences calls on the same fence.");
5633
5634     ASSERT_NO_FATAL_FAILURE(InitState());
5635     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5636         return;
5637
5638     m_errorMonitor->ExpectSuccess();
5639
5640     VkFence fence;
5641     VkFenceCreateInfo fence_create_info{};
5642     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5643     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5644
5645     VkSemaphore semaphore;
5646     VkSemaphoreCreateInfo semaphore_create_info{};
5647     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5648     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5649
5650     VkCommandPool command_pool;
5651     VkCommandPoolCreateInfo pool_create_info{};
5652     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5653     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5654     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5655     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5656
5657     VkCommandBuffer command_buffer[2];
5658     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5659     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5660     command_buffer_allocate_info.commandPool = command_pool;
5661     command_buffer_allocate_info.commandBufferCount = 2;
5662     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5663     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5664
5665     VkQueue queue = VK_NULL_HANDLE;
5666     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5667
5668     {
5669         VkCommandBufferBeginInfo begin_info{};
5670         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5671         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5672
5673         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5674                              nullptr, 0, nullptr, 0, nullptr);
5675
5676         VkViewport viewport{};
5677         viewport.maxDepth = 1.0f;
5678         viewport.minDepth = 0.0f;
5679         viewport.width = 512;
5680         viewport.height = 512;
5681         viewport.x = 0;
5682         viewport.y = 0;
5683         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5684         vkEndCommandBuffer(command_buffer[0]);
5685     }
5686     {
5687         VkCommandBufferBeginInfo begin_info{};
5688         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5689         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5690
5691         VkViewport viewport{};
5692         viewport.maxDepth = 1.0f;
5693         viewport.minDepth = 0.0f;
5694         viewport.width = 512;
5695         viewport.height = 512;
5696         viewport.x = 0;
5697         viewport.y = 0;
5698         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5699         vkEndCommandBuffer(command_buffer[1]);
5700     }
5701     {
5702         VkSubmitInfo submit_info{};
5703         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5704         submit_info.commandBufferCount = 1;
5705         submit_info.pCommandBuffers = &command_buffer[0];
5706         submit_info.signalSemaphoreCount = 1;
5707         submit_info.pSignalSemaphores = &semaphore;
5708         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5709     }
5710     {
5711         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5712         VkSubmitInfo submit_info{};
5713         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5714         submit_info.commandBufferCount = 1;
5715         submit_info.pCommandBuffers = &command_buffer[1];
5716         submit_info.waitSemaphoreCount = 1;
5717         submit_info.pWaitSemaphores = &semaphore;
5718         submit_info.pWaitDstStageMask = flags;
5719         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5720     }
5721
5722     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5723     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5724
5725     vkDestroyFence(m_device->device(), fence, nullptr);
5726     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5727     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5728     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5729
5730     m_errorMonitor->VerifyNotFound();
5731 }
5732
5733 TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
5734
5735     ASSERT_NO_FATAL_FAILURE(InitState());
5736     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
5737         printf("Test requires two queues, skipping\n");
5738         return;
5739     }
5740
5741     VkResult err;
5742
5743     m_errorMonitor->ExpectSuccess();
5744
5745     VkQueue q0 = m_device->m_queue;
5746     VkQueue q1 = nullptr;
5747     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
5748     ASSERT_NE(q1, nullptr);
5749
5750     // An (empty) command buffer. We must have work in the first submission --
5751     // the layer treats unfenced work differently from fenced work.
5752     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
5753     VkCommandPool pool;
5754     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
5755     ASSERT_VK_SUCCESS(err);
5756     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
5757                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
5758     VkCommandBuffer cb;
5759     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
5760     ASSERT_VK_SUCCESS(err);
5761     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
5762     err = vkBeginCommandBuffer(cb, &cbbi);
5763     ASSERT_VK_SUCCESS(err);
5764     err = vkEndCommandBuffer(cb);
5765     ASSERT_VK_SUCCESS(err);
5766
5767     // A semaphore
5768     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5769     VkSemaphore s;
5770     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
5771     ASSERT_VK_SUCCESS(err);
5772
5773     // First submission, to q0
5774     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
5775
5776     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
5777     ASSERT_VK_SUCCESS(err);
5778
5779     // Second submission, to q1, waiting on s
5780     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
5781     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
5782
5783     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
5784     ASSERT_VK_SUCCESS(err);
5785
5786     // Wait for q0 idle
5787     err = vkQueueWaitIdle(q0);
5788     ASSERT_VK_SUCCESS(err);
5789
5790     // Command buffer should have been completed (it was on q0); reset the pool.
5791     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
5792
5793     m_errorMonitor->VerifyNotFound();
5794
5795     // Force device completely idle and clean up resources
5796     vkDeviceWaitIdle(m_device->device());
5797     vkDestroyCommandPool(m_device->device(), pool, nullptr);
5798     vkDestroySemaphore(m_device->device(), s, nullptr);
5799 }
5800
5801 // This is a positive test.  No errors should be generated.
5802 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
5803
5804     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5805                      "submitted on separate queues, the second having a fence, "
5806                      "followed by a WaitForFences call.");
5807
5808     ASSERT_NO_FATAL_FAILURE(InitState());
5809     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5810         return;
5811
5812     m_errorMonitor->ExpectSuccess();
5813
5814     ASSERT_NO_FATAL_FAILURE(InitState());
5815     VkFence fence;
5816     VkFenceCreateInfo fence_create_info{};
5817     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5818     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5819
5820     VkSemaphore semaphore;
5821     VkSemaphoreCreateInfo semaphore_create_info{};
5822     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5823     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5824
5825     VkCommandPool command_pool;
5826     VkCommandPoolCreateInfo pool_create_info{};
5827     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5828     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5829     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5830     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5831
5832     VkCommandBuffer command_buffer[2];
5833     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5834     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5835     command_buffer_allocate_info.commandPool = command_pool;
5836     command_buffer_allocate_info.commandBufferCount = 2;
5837     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5838     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5839
5840     VkQueue queue = VK_NULL_HANDLE;
5841     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5842
5843     {
5844         VkCommandBufferBeginInfo begin_info{};
5845         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5846         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5847
5848         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5849                              nullptr, 0, nullptr, 0, nullptr);
5850
5851         VkViewport viewport{};
5852         viewport.maxDepth = 1.0f;
5853         viewport.minDepth = 0.0f;
5854         viewport.width = 512;
5855         viewport.height = 512;
5856         viewport.x = 0;
5857         viewport.y = 0;
5858         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5859         vkEndCommandBuffer(command_buffer[0]);
5860     }
5861     {
5862         VkCommandBufferBeginInfo begin_info{};
5863         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5864         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5865
5866         VkViewport viewport{};
5867         viewport.maxDepth = 1.0f;
5868         viewport.minDepth = 0.0f;
5869         viewport.width = 512;
5870         viewport.height = 512;
5871         viewport.x = 0;
5872         viewport.y = 0;
5873         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5874         vkEndCommandBuffer(command_buffer[1]);
5875     }
5876     {
5877         VkSubmitInfo submit_info{};
5878         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5879         submit_info.commandBufferCount = 1;
5880         submit_info.pCommandBuffers = &command_buffer[0];
5881         submit_info.signalSemaphoreCount = 1;
5882         submit_info.pSignalSemaphores = &semaphore;
5883         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5884     }
5885     {
5886         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5887         VkSubmitInfo submit_info{};
5888         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5889         submit_info.commandBufferCount = 1;
5890         submit_info.pCommandBuffers = &command_buffer[1];
5891         submit_info.waitSemaphoreCount = 1;
5892         submit_info.pWaitSemaphores = &semaphore;
5893         submit_info.pWaitDstStageMask = flags;
5894         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5895     }
5896
5897     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5898
5899     vkDestroyFence(m_device->device(), fence, nullptr);
5900     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5901     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5902     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5903
5904     m_errorMonitor->VerifyNotFound();
5905 }
5906
5907 // This is a positive test.  No errors should be generated.
5908 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
5909
5910     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5911                      "on the same queue, sharing a signal/wait semaphore, the "
5912                      "second having a fence, "
5913                      "followed by a WaitForFences call.");
5914
5915     m_errorMonitor->ExpectSuccess();
5916
5917     ASSERT_NO_FATAL_FAILURE(InitState());
5918     VkFence fence;
5919     VkFenceCreateInfo fence_create_info{};
5920     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5921     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5922
5923     VkSemaphore semaphore;
5924     VkSemaphoreCreateInfo semaphore_create_info{};
5925     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5926     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5927
5928     VkCommandPool command_pool;
5929     VkCommandPoolCreateInfo pool_create_info{};
5930     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5931     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5932     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5933     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5934
5935     VkCommandBuffer command_buffer[2];
5936     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5937     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5938     command_buffer_allocate_info.commandPool = command_pool;
5939     command_buffer_allocate_info.commandBufferCount = 2;
5940     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5941     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5942
5943     {
5944         VkCommandBufferBeginInfo begin_info{};
5945         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5946         vkBeginCommandBuffer(command_buffer[0], &begin_info);
5947
5948         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5949                              nullptr, 0, nullptr, 0, nullptr);
5950
5951         VkViewport viewport{};
5952         viewport.maxDepth = 1.0f;
5953         viewport.minDepth = 0.0f;
5954         viewport.width = 512;
5955         viewport.height = 512;
5956         viewport.x = 0;
5957         viewport.y = 0;
5958         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5959         vkEndCommandBuffer(command_buffer[0]);
5960     }
5961     {
5962         VkCommandBufferBeginInfo begin_info{};
5963         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5964         vkBeginCommandBuffer(command_buffer[1], &begin_info);
5965
5966         VkViewport viewport{};
5967         viewport.maxDepth = 1.0f;
5968         viewport.minDepth = 0.0f;
5969         viewport.width = 512;
5970         viewport.height = 512;
5971         viewport.x = 0;
5972         viewport.y = 0;
5973         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5974         vkEndCommandBuffer(command_buffer[1]);
5975     }
5976     {
5977         VkSubmitInfo submit_info{};
5978         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5979         submit_info.commandBufferCount = 1;
5980         submit_info.pCommandBuffers = &command_buffer[0];
5981         submit_info.signalSemaphoreCount = 1;
5982         submit_info.pSignalSemaphores = &semaphore;
5983         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5984     }
5985     {
5986         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5987         VkSubmitInfo submit_info{};
5988         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5989         submit_info.commandBufferCount = 1;
5990         submit_info.pCommandBuffers = &command_buffer[1];
5991         submit_info.waitSemaphoreCount = 1;
5992         submit_info.pWaitSemaphores = &semaphore;
5993         submit_info.pWaitDstStageMask = flags;
5994         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5995     }
5996
5997     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5998
5999     vkDestroyFence(m_device->device(), fence, nullptr);
6000     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6001     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6002     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6003
6004     m_errorMonitor->VerifyNotFound();
6005 }
6006
6007 // This is a positive test.  No errors should be generated.
6008 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
6009
6010     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6011                      "on the same queue, no fences, followed by a third QueueSubmit with NO "
6012                      "SubmitInfos but with a fence, followed by a WaitForFences call.");
6013
6014     m_errorMonitor->ExpectSuccess();
6015
6016     ASSERT_NO_FATAL_FAILURE(InitState());
6017     VkFence fence;
6018     VkFenceCreateInfo fence_create_info{};
6019     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6020     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6021
6022     VkCommandPool command_pool;
6023     VkCommandPoolCreateInfo pool_create_info{};
6024     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6025     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6026     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6027     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6028
6029     VkCommandBuffer command_buffer[2];
6030     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6031     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6032     command_buffer_allocate_info.commandPool = command_pool;
6033     command_buffer_allocate_info.commandBufferCount = 2;
6034     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6035     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6036
6037     {
6038         VkCommandBufferBeginInfo begin_info{};
6039         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6040         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6041
6042         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6043                              nullptr, 0, nullptr, 0, nullptr);
6044
6045         VkViewport viewport{};
6046         viewport.maxDepth = 1.0f;
6047         viewport.minDepth = 0.0f;
6048         viewport.width = 512;
6049         viewport.height = 512;
6050         viewport.x = 0;
6051         viewport.y = 0;
6052         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6053         vkEndCommandBuffer(command_buffer[0]);
6054     }
6055     {
6056         VkCommandBufferBeginInfo begin_info{};
6057         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6058         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6059
6060         VkViewport viewport{};
6061         viewport.maxDepth = 1.0f;
6062         viewport.minDepth = 0.0f;
6063         viewport.width = 512;
6064         viewport.height = 512;
6065         viewport.x = 0;
6066         viewport.y = 0;
6067         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6068         vkEndCommandBuffer(command_buffer[1]);
6069     }
6070     {
6071         VkSubmitInfo submit_info{};
6072         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6073         submit_info.commandBufferCount = 1;
6074         submit_info.pCommandBuffers = &command_buffer[0];
6075         submit_info.signalSemaphoreCount = 0;
6076         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6077         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6078     }
6079     {
6080         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6081         VkSubmitInfo submit_info{};
6082         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6083         submit_info.commandBufferCount = 1;
6084         submit_info.pCommandBuffers = &command_buffer[1];
6085         submit_info.waitSemaphoreCount = 0;
6086         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6087         submit_info.pWaitDstStageMask = flags;
6088         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6089     }
6090
6091     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
6092
6093     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6094     ASSERT_VK_SUCCESS(err);
6095
6096     vkDestroyFence(m_device->device(), fence, nullptr);
6097     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6098     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6099
6100     m_errorMonitor->VerifyNotFound();
6101 }
6102
6103 // This is a positive test.  No errors should be generated.
6104 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
6105
6106     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6107                      "on the same queue, the second having a fence, followed "
6108                      "by a WaitForFences call.");
6109
6110     m_errorMonitor->ExpectSuccess();
6111
6112     ASSERT_NO_FATAL_FAILURE(InitState());
6113     VkFence fence;
6114     VkFenceCreateInfo fence_create_info{};
6115     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6116     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6117
6118     VkCommandPool command_pool;
6119     VkCommandPoolCreateInfo pool_create_info{};
6120     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6121     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6122     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6123     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6124
6125     VkCommandBuffer command_buffer[2];
6126     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6127     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6128     command_buffer_allocate_info.commandPool = command_pool;
6129     command_buffer_allocate_info.commandBufferCount = 2;
6130     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6131     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6132
6133     {
6134         VkCommandBufferBeginInfo begin_info{};
6135         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6136         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6137
6138         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6139                              nullptr, 0, nullptr, 0, nullptr);
6140
6141         VkViewport viewport{};
6142         viewport.maxDepth = 1.0f;
6143         viewport.minDepth = 0.0f;
6144         viewport.width = 512;
6145         viewport.height = 512;
6146         viewport.x = 0;
6147         viewport.y = 0;
6148         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6149         vkEndCommandBuffer(command_buffer[0]);
6150     }
6151     {
6152         VkCommandBufferBeginInfo begin_info{};
6153         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6154         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6155
6156         VkViewport viewport{};
6157         viewport.maxDepth = 1.0f;
6158         viewport.minDepth = 0.0f;
6159         viewport.width = 512;
6160         viewport.height = 512;
6161         viewport.x = 0;
6162         viewport.y = 0;
6163         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6164         vkEndCommandBuffer(command_buffer[1]);
6165     }
6166     {
6167         VkSubmitInfo submit_info{};
6168         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6169         submit_info.commandBufferCount = 1;
6170         submit_info.pCommandBuffers = &command_buffer[0];
6171         submit_info.signalSemaphoreCount = 0;
6172         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6173         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6174     }
6175     {
6176         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6177         VkSubmitInfo submit_info{};
6178         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6179         submit_info.commandBufferCount = 1;
6180         submit_info.pCommandBuffers = &command_buffer[1];
6181         submit_info.waitSemaphoreCount = 0;
6182         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6183         submit_info.pWaitDstStageMask = flags;
6184         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
6185     }
6186
6187     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6188
6189     vkDestroyFence(m_device->device(), fence, nullptr);
6190     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6191     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6192
6193     m_errorMonitor->VerifyNotFound();
6194 }
6195
6196 // This is a positive test.  No errors should be generated.
6197 TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
6198
6199     TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
6200                      "QueueSubmit call followed by a WaitForFences call.");
6201     ASSERT_NO_FATAL_FAILURE(InitState());
6202
6203     m_errorMonitor->ExpectSuccess();
6204
6205     VkFence fence;
6206     VkFenceCreateInfo fence_create_info{};
6207     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6208     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6209
6210     VkSemaphore semaphore;
6211     VkSemaphoreCreateInfo semaphore_create_info{};
6212     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6213     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
6214
6215     VkCommandPool command_pool;
6216     VkCommandPoolCreateInfo pool_create_info{};
6217     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6218     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6219     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6220     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6221
6222     VkCommandBuffer command_buffer[2];
6223     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6224     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6225     command_buffer_allocate_info.commandPool = command_pool;
6226     command_buffer_allocate_info.commandBufferCount = 2;
6227     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6228     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6229
6230     {
6231         VkCommandBufferBeginInfo begin_info{};
6232         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6233         vkBeginCommandBuffer(command_buffer[0], &begin_info);
6234
6235         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6236                              nullptr, 0, nullptr, 0, nullptr);
6237
6238         VkViewport viewport{};
6239         viewport.maxDepth = 1.0f;
6240         viewport.minDepth = 0.0f;
6241         viewport.width = 512;
6242         viewport.height = 512;
6243         viewport.x = 0;
6244         viewport.y = 0;
6245         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6246         vkEndCommandBuffer(command_buffer[0]);
6247     }
6248     {
6249         VkCommandBufferBeginInfo begin_info{};
6250         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6251         vkBeginCommandBuffer(command_buffer[1], &begin_info);
6252
6253         VkViewport viewport{};
6254         viewport.maxDepth = 1.0f;
6255         viewport.minDepth = 0.0f;
6256         viewport.width = 512;
6257         viewport.height = 512;
6258         viewport.x = 0;
6259         viewport.y = 0;
6260         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6261         vkEndCommandBuffer(command_buffer[1]);
6262     }
6263     {
6264         VkSubmitInfo submit_info[2];
6265         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6266
6267         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6268         submit_info[0].pNext = NULL;
6269         submit_info[0].commandBufferCount = 1;
6270         submit_info[0].pCommandBuffers = &command_buffer[0];
6271         submit_info[0].signalSemaphoreCount = 1;
6272         submit_info[0].pSignalSemaphores = &semaphore;
6273         submit_info[0].waitSemaphoreCount = 0;
6274         submit_info[0].pWaitSemaphores = NULL;
6275         submit_info[0].pWaitDstStageMask = 0;
6276
6277         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6278         submit_info[1].pNext = NULL;
6279         submit_info[1].commandBufferCount = 1;
6280         submit_info[1].pCommandBuffers = &command_buffer[1];
6281         submit_info[1].waitSemaphoreCount = 1;
6282         submit_info[1].pWaitSemaphores = &semaphore;
6283         submit_info[1].pWaitDstStageMask = flags;
6284         submit_info[1].signalSemaphoreCount = 0;
6285         submit_info[1].pSignalSemaphores = NULL;
6286         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
6287     }
6288
6289     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6290
6291     vkDestroyFence(m_device->device(), fence, nullptr);
6292     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6293     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6294     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6295
6296     m_errorMonitor->VerifyNotFound();
6297 }
6298
6299 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
6300     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
6301                      "state is required but not correctly bound.");
6302
6303     ASSERT_NO_FATAL_FAILURE(InitState());
6304     // Dynamic depth bias
6305     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
6306     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias);
6307     m_errorMonitor->VerifyFound();
6308 }
6309
6310 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
6311     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic "
6312                      "state is required but not correctly bound.");
6313
6314     ASSERT_NO_FATAL_FAILURE(InitState());
6315     // Dynamic line width
6316     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
6317     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth);
6318     m_errorMonitor->VerifyFound();
6319 }
6320
6321 TEST_F(VkLayerTest, DynamicViewportNotBound) {
6322     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic "
6323                      "state is required but not correctly bound.");
6324
6325     ASSERT_NO_FATAL_FAILURE(InitState());
6326     // Dynamic viewport state
6327     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, but were not provided");
6328     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
6329     m_errorMonitor->VerifyFound();
6330 }
6331
6332 TEST_F(VkLayerTest, DynamicScissorNotBound) {
6333     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic "
6334                      "state is required but not correctly bound.");
6335
6336     ASSERT_NO_FATAL_FAILURE(InitState());
6337     // Dynamic scissor state
6338     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, but were not provided");
6339     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
6340     m_errorMonitor->VerifyFound();
6341 }
6342
6343 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
6344     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants "
6345                      "dynamic state is required but not correctly bound.");
6346
6347     ASSERT_NO_FATAL_FAILURE(InitState());
6348     // Dynamic blend constant state
6349     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6350                                          "Dynamic blend constants state not set for this command buffer");
6351     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend);
6352     m_errorMonitor->VerifyFound();
6353 }
6354
6355 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
6356     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic "
6357                      "state is required but not correctly bound.");
6358
6359     ASSERT_NO_FATAL_FAILURE(InitState());
6360     if (!m_device->phy().features().depthBounds) {
6361         printf("Device does not support depthBounds test; skipped.\n");
6362         return;
6363     }
6364     // Dynamic depth bounds
6365     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6366                                          "Dynamic depth bounds state not set for this command buffer");
6367     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds);
6368     m_errorMonitor->VerifyFound();
6369 }
6370
6371 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
6372     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic "
6373                      "state is required but not correctly bound.");
6374
6375     ASSERT_NO_FATAL_FAILURE(InitState());
6376     // Dynamic stencil read mask
6377     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6378                                          "Dynamic stencil read mask state not set for this command buffer");
6379     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask);
6380     m_errorMonitor->VerifyFound();
6381 }
6382
6383 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
6384     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic"
6385                      " state is required but not correctly bound.");
6386
6387     ASSERT_NO_FATAL_FAILURE(InitState());
6388     // Dynamic stencil write mask
6389     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6390                                          "Dynamic stencil write mask state not set for this command buffer");
6391     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask);
6392     m_errorMonitor->VerifyFound();
6393 }
6394
6395 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
6396     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic "
6397                      "state is required but not correctly bound.");
6398
6399     ASSERT_NO_FATAL_FAILURE(InitState());
6400     // Dynamic stencil reference
6401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6402                                          "Dynamic stencil reference state not set for this command buffer");
6403     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference);
6404     m_errorMonitor->VerifyFound();
6405 }
6406
6407 TEST_F(VkLayerTest, IndexBufferNotBound) {
6408     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
6409
6410     ASSERT_NO_FATAL_FAILURE(InitState());
6411     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6412                                          "Index buffer object not bound to this command buffer when Indexed ");
6413     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer);
6414     m_errorMonitor->VerifyFound();
6415 }
6416
6417 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
6418     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6419                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
6420                                          "been submitted");
6421
6422     ASSERT_NO_FATAL_FAILURE(InitState());
6423     ASSERT_NO_FATAL_FAILURE(InitViewport());
6424     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6425
6426     // We luck out b/c by default the framework creates CB w/ the
6427     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
6428     BeginCommandBuffer();
6429     m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
6430     EndCommandBuffer();
6431
6432     // Bypass framework since it does the waits automatically
6433     VkResult err = VK_SUCCESS;
6434     VkSubmitInfo submit_info;
6435     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6436     submit_info.pNext = NULL;
6437     submit_info.waitSemaphoreCount = 0;
6438     submit_info.pWaitSemaphores = NULL;
6439     submit_info.pWaitDstStageMask = NULL;
6440     submit_info.commandBufferCount = 1;
6441     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6442     submit_info.signalSemaphoreCount = 0;
6443     submit_info.pSignalSemaphores = NULL;
6444
6445     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6446     ASSERT_VK_SUCCESS(err);
6447
6448     // Cause validation error by re-submitting cmd buffer that should only be
6449     // submitted once
6450     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6451
6452     m_errorMonitor->VerifyFound();
6453 }
6454
6455 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
6456     // Initiate Draw w/o a PSO bound
6457     VkResult err;
6458
6459     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of "
6460                                                                         "type "
6461                                                                         "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ");
6462
6463     ASSERT_NO_FATAL_FAILURE(InitState());
6464     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6465
6466     // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
6467     // descriptor from it
6468     VkDescriptorPoolSize ds_type_count = {};
6469     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
6470     ds_type_count.descriptorCount = 1;
6471
6472     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6473     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6474     ds_pool_ci.pNext = NULL;
6475     ds_pool_ci.flags = 0;
6476     ds_pool_ci.maxSets = 1;
6477     ds_pool_ci.poolSizeCount = 1;
6478     ds_pool_ci.pPoolSizes = &ds_type_count;
6479
6480     VkDescriptorPool ds_pool;
6481     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6482     ASSERT_VK_SUCCESS(err);
6483
6484     VkDescriptorSetLayoutBinding dsl_binding = {};
6485     dsl_binding.binding = 0;
6486     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6487     dsl_binding.descriptorCount = 1;
6488     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6489     dsl_binding.pImmutableSamplers = NULL;
6490
6491     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6492     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6493     ds_layout_ci.pNext = NULL;
6494     ds_layout_ci.bindingCount = 1;
6495     ds_layout_ci.pBindings = &dsl_binding;
6496
6497     VkDescriptorSetLayout ds_layout;
6498     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6499     ASSERT_VK_SUCCESS(err);
6500
6501     VkDescriptorSet descriptorSet;
6502     VkDescriptorSetAllocateInfo alloc_info = {};
6503     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6504     alloc_info.descriptorSetCount = 1;
6505     alloc_info.descriptorPool = ds_pool;
6506     alloc_info.pSetLayouts = &ds_layout;
6507     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6508
6509     m_errorMonitor->VerifyFound();
6510
6511     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6512     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6513 }
6514
6515 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
6516     VkResult err;
6517
6518     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6519                                          "It is invalid to call vkFreeDescriptorSets() with a pool created "
6520                                          "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
6521
6522     ASSERT_NO_FATAL_FAILURE(InitState());
6523     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6524
6525     VkDescriptorPoolSize ds_type_count = {};
6526     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6527     ds_type_count.descriptorCount = 1;
6528
6529     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6530     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6531     ds_pool_ci.pNext = NULL;
6532     ds_pool_ci.maxSets = 1;
6533     ds_pool_ci.poolSizeCount = 1;
6534     ds_pool_ci.flags = 0;
6535     // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
6536     // app can only call vkResetDescriptorPool on this pool.;
6537     ds_pool_ci.pPoolSizes = &ds_type_count;
6538
6539     VkDescriptorPool ds_pool;
6540     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6541     ASSERT_VK_SUCCESS(err);
6542
6543     VkDescriptorSetLayoutBinding dsl_binding = {};
6544     dsl_binding.binding = 0;
6545     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6546     dsl_binding.descriptorCount = 1;
6547     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6548     dsl_binding.pImmutableSamplers = NULL;
6549
6550     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6551     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6552     ds_layout_ci.pNext = NULL;
6553     ds_layout_ci.bindingCount = 1;
6554     ds_layout_ci.pBindings = &dsl_binding;
6555
6556     VkDescriptorSetLayout ds_layout;
6557     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6558     ASSERT_VK_SUCCESS(err);
6559
6560     VkDescriptorSet descriptorSet;
6561     VkDescriptorSetAllocateInfo alloc_info = {};
6562     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6563     alloc_info.descriptorSetCount = 1;
6564     alloc_info.descriptorPool = ds_pool;
6565     alloc_info.pSetLayouts = &ds_layout;
6566     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6567     ASSERT_VK_SUCCESS(err);
6568
6569     err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
6570     m_errorMonitor->VerifyFound();
6571
6572     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6573     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6574 }
6575
6576 TEST_F(VkLayerTest, InvalidDescriptorPool) {
6577     // Attempt to clear Descriptor Pool with bad object.
6578     // ObjectTracker should catch this.
6579
6580     ASSERT_NO_FATAL_FAILURE(InitState());
6581     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001");
6582     uint64_t fake_pool_handle = 0xbaad6001;
6583     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
6584     vkResetDescriptorPool(device(), bad_pool, 0);
6585     m_errorMonitor->VerifyFound();
6586 }
6587
6588 TEST_F(VkLayerTest, InvalidDescriptorSet) {
6589     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
6590     // ObjectTracker should catch this.
6591     // Create a valid cmd buffer
6592     // call vkCmdBindDescriptorSets w/ false Descriptor Set
6593
6594     uint64_t fake_set_handle = 0xbaad6001;
6595     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
6596     VkResult err;
6597     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001");
6598
6599     ASSERT_NO_FATAL_FAILURE(InitState());
6600
6601     VkDescriptorSetLayoutBinding layout_bindings[1] = {};
6602     layout_bindings[0].binding = 0;
6603     layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6604     layout_bindings[0].descriptorCount = 1;
6605     layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
6606     layout_bindings[0].pImmutableSamplers = NULL;
6607
6608     VkDescriptorSetLayout descriptor_set_layout;
6609     VkDescriptorSetLayoutCreateInfo dslci = {};
6610     dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6611     dslci.pNext = NULL;
6612     dslci.bindingCount = 1;
6613     dslci.pBindings = layout_bindings;
6614     err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout);
6615     ASSERT_VK_SUCCESS(err);
6616
6617     VkPipelineLayout pipeline_layout;
6618     VkPipelineLayoutCreateInfo plci = {};
6619     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6620     plci.pNext = NULL;
6621     plci.setLayoutCount = 1;
6622     plci.pSetLayouts = &descriptor_set_layout;
6623     err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6624     ASSERT_VK_SUCCESS(err);
6625
6626     BeginCommandBuffer();
6627     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0,
6628                             NULL);
6629     m_errorMonitor->VerifyFound();
6630     EndCommandBuffer();
6631     vkDestroyPipelineLayout(device(), pipeline_layout, NULL);
6632     vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL);
6633 }
6634
6635 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
6636     // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
6637     // ObjectTracker should catch this.
6638     uint64_t fake_layout_handle = 0xbaad6001;
6639     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
6640     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001");
6641     ASSERT_NO_FATAL_FAILURE(InitState());
6642     VkPipelineLayout pipeline_layout;
6643     VkPipelineLayoutCreateInfo plci = {};
6644     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6645     plci.pNext = NULL;
6646     plci.setLayoutCount = 1;
6647     plci.pSetLayouts = &bad_layout;
6648     vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6649
6650     m_errorMonitor->VerifyFound();
6651 }
6652
6653 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
6654     TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
6655                      "1) A uniform buffer update must have a valid buffer index."
6656                      "2) When using an array of descriptors in a single WriteDescriptor,"
6657                      "     the descriptor types and stageflags must all be the same."
6658                      "3) Immutable Sampler state must match across descriptors");
6659
6660     const char *invalid_BufferInfo_ErrorMessage =
6661         "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
6662         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
6663         "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
6664     const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set ";
6665     const char *immutable_ErrorMessage = "Attempting write update to descriptor set ";
6666
6667     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
6668
6669     ASSERT_NO_FATAL_FAILURE(InitState());
6670     VkDescriptorPoolSize ds_type_count[4] = {};
6671     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6672     ds_type_count[0].descriptorCount = 1;
6673     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6674     ds_type_count[1].descriptorCount = 1;
6675     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6676     ds_type_count[2].descriptorCount = 1;
6677     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
6678     ds_type_count[3].descriptorCount = 1;
6679
6680     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6681     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6682     ds_pool_ci.maxSets = 1;
6683     ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
6684     ds_pool_ci.pPoolSizes = ds_type_count;
6685
6686     VkDescriptorPool ds_pool;
6687     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6688     ASSERT_VK_SUCCESS(err);
6689
6690     VkDescriptorSetLayoutBinding layout_binding[3] = {};
6691     layout_binding[0].binding = 0;
6692     layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6693     layout_binding[0].descriptorCount = 1;
6694     layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
6695     layout_binding[0].pImmutableSamplers = NULL;
6696
6697     layout_binding[1].binding = 1;
6698     layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6699     layout_binding[1].descriptorCount = 1;
6700     layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6701     layout_binding[1].pImmutableSamplers = NULL;
6702
6703     VkSamplerCreateInfo sampler_ci = {};
6704     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6705     sampler_ci.pNext = NULL;
6706     sampler_ci.magFilter = VK_FILTER_NEAREST;
6707     sampler_ci.minFilter = VK_FILTER_NEAREST;
6708     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
6709     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6710     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6711     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6712     sampler_ci.mipLodBias = 1.0;
6713     sampler_ci.anisotropyEnable = VK_FALSE;
6714     sampler_ci.maxAnisotropy = 1;
6715     sampler_ci.compareEnable = VK_FALSE;
6716     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
6717     sampler_ci.minLod = 1.0;
6718     sampler_ci.maxLod = 1.0;
6719     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
6720     sampler_ci.unnormalizedCoordinates = VK_FALSE;
6721     VkSampler sampler;
6722
6723     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
6724     ASSERT_VK_SUCCESS(err);
6725
6726     layout_binding[2].binding = 2;
6727     layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6728     layout_binding[2].descriptorCount = 1;
6729     layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6730     layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
6731
6732     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6733     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6734     ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
6735     ds_layout_ci.pBindings = layout_binding;
6736     VkDescriptorSetLayout ds_layout;
6737     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6738     ASSERT_VK_SUCCESS(err);
6739
6740     VkDescriptorSetAllocateInfo alloc_info = {};
6741     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6742     alloc_info.descriptorSetCount = 1;
6743     alloc_info.descriptorPool = ds_pool;
6744     alloc_info.pSetLayouts = &ds_layout;
6745     VkDescriptorSet descriptorSet;
6746     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6747     ASSERT_VK_SUCCESS(err);
6748
6749     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6750     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6751     pipeline_layout_ci.pNext = NULL;
6752     pipeline_layout_ci.setLayoutCount = 1;
6753     pipeline_layout_ci.pSetLayouts = &ds_layout;
6754
6755     VkPipelineLayout pipeline_layout;
6756     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6757     ASSERT_VK_SUCCESS(err);
6758
6759     VkWriteDescriptorSet descriptor_write = {};
6760     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6761     descriptor_write.dstSet = descriptorSet;
6762     descriptor_write.dstBinding = 0;
6763     descriptor_write.descriptorCount = 1;
6764     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6765
6766     // 1) The uniform buffer is intentionally invalid here
6767     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6768     m_errorMonitor->VerifyFound();
6769
6770     // Create a buffer to update the descriptor with
6771     uint32_t qfi = 0;
6772     VkBufferCreateInfo buffCI = {};
6773     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6774     buffCI.size = 1024;
6775     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
6776     buffCI.queueFamilyIndexCount = 1;
6777     buffCI.pQueueFamilyIndices = &qfi;
6778
6779     VkBuffer dyub;
6780     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
6781     ASSERT_VK_SUCCESS(err);
6782     VkDescriptorBufferInfo buffInfo = {};
6783     buffInfo.buffer = dyub;
6784     buffInfo.offset = 0;
6785     buffInfo.range = 1024;
6786
6787     descriptor_write.pBufferInfo = &buffInfo;
6788     descriptor_write.descriptorCount = 2;
6789
6790     // 2) The stateFlags don't match between the first and second descriptor
6791     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
6792     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6793     m_errorMonitor->VerifyFound();
6794
6795     // 3) The second descriptor has a null_ptr pImmutableSamplers and
6796     // the third descriptor contains an immutable sampler
6797     descriptor_write.dstBinding = 1;
6798     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6799
6800     // Make pImageInfo index non-null to avoid complaints of it missing
6801     VkDescriptorImageInfo imageInfo = {};
6802     imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6803     descriptor_write.pImageInfo = &imageInfo;
6804     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
6805     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6806     m_errorMonitor->VerifyFound();
6807
6808     vkDestroyBuffer(m_device->device(), dyub, NULL);
6809     vkDestroySampler(m_device->device(), sampler, NULL);
6810     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
6811     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6812     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6813 }
6814
6815 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
6816     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
6817                      "due to a buffer dependency being destroyed.");
6818     ASSERT_NO_FATAL_FAILURE(InitState());
6819
6820     VkBuffer buffer;
6821     VkDeviceMemory mem;
6822     VkMemoryRequirements mem_reqs;
6823
6824     VkBufferCreateInfo buf_info = {};
6825     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6826     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
6827     buf_info.size = 256;
6828     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
6829     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
6830     ASSERT_VK_SUCCESS(err);
6831
6832     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
6833
6834     VkMemoryAllocateInfo alloc_info = {};
6835     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6836     alloc_info.allocationSize = 256;
6837     bool pass = false;
6838     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6839     if (!pass) {
6840         vkDestroyBuffer(m_device->device(), buffer, NULL);
6841         return;
6842     }
6843     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
6844     ASSERT_VK_SUCCESS(err);
6845
6846     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
6847     ASSERT_VK_SUCCESS(err);
6848
6849     m_commandBuffer->BeginCommandBuffer();
6850     vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
6851     m_commandBuffer->EndCommandBuffer();
6852
6853     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
6854     // Destroy buffer dependency prior to submit to cause ERROR
6855     vkDestroyBuffer(m_device->device(), buffer, NULL);
6856
6857     VkSubmitInfo submit_info = {};
6858     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6859     submit_info.commandBufferCount = 1;
6860     submit_info.pCommandBuffers = &m_commandBuffer->handle();
6861     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6862
6863     m_errorMonitor->VerifyFound();
6864     vkFreeMemory(m_device->handle(), mem, NULL);
6865 }
6866
6867 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
6868     TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
6869
6870     ASSERT_NO_FATAL_FAILURE(InitState());
6871     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6872
6873     VkDescriptorPoolSize ds_type_count;
6874     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6875     ds_type_count.descriptorCount = 1;
6876
6877     VkDescriptorPoolCreateInfo ds_pool_ci = {};
6878     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6879     ds_pool_ci.maxSets = 1;
6880     ds_pool_ci.poolSizeCount = 1;
6881     ds_pool_ci.pPoolSizes = &ds_type_count;
6882
6883     VkDescriptorPool ds_pool;
6884     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6885     ASSERT_VK_SUCCESS(err);
6886
6887     VkDescriptorSetLayoutBinding layout_binding;
6888     layout_binding.binding = 0;
6889     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6890     layout_binding.descriptorCount = 1;
6891     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6892     layout_binding.pImmutableSamplers = NULL;
6893
6894     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6895     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6896     ds_layout_ci.bindingCount = 1;
6897     ds_layout_ci.pBindings = &layout_binding;
6898     VkDescriptorSetLayout ds_layout;
6899     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6900     ASSERT_VK_SUCCESS(err);
6901
6902     VkDescriptorSetAllocateInfo alloc_info = {};
6903     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6904     alloc_info.descriptorSetCount = 1;
6905     alloc_info.descriptorPool = ds_pool;
6906     alloc_info.pSetLayouts = &ds_layout;
6907     VkDescriptorSet descriptor_set;
6908     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
6909     ASSERT_VK_SUCCESS(err);
6910
6911     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6912     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6913     pipeline_layout_ci.pNext = NULL;
6914     pipeline_layout_ci.setLayoutCount = 1;
6915     pipeline_layout_ci.pSetLayouts = &ds_layout;
6916
6917     VkPipelineLayout pipeline_layout;
6918     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6919     ASSERT_VK_SUCCESS(err);
6920
6921     VkBuffer buffer;
6922     uint32_t queue_family_index = 0;
6923     VkBufferCreateInfo buffer_create_info = {};
6924     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6925     buffer_create_info.size = 1024;
6926     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
6927     buffer_create_info.queueFamilyIndexCount = 1;
6928     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
6929
6930     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
6931     ASSERT_VK_SUCCESS(err);
6932
6933     VkMemoryRequirements memory_reqs;
6934     VkDeviceMemory buffer_memory;
6935
6936     VkMemoryAllocateInfo memory_info = {};
6937     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6938     memory_info.allocationSize = 0;
6939     memory_info.memoryTypeIndex = 0;
6940
6941     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
6942     memory_info.allocationSize = memory_reqs.size;
6943     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
6944     ASSERT_TRUE(pass);
6945
6946     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
6947     ASSERT_VK_SUCCESS(err);
6948     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
6949     ASSERT_VK_SUCCESS(err);
6950
6951     VkBufferView view;
6952     VkBufferViewCreateInfo bvci = {};
6953     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
6954     bvci.buffer = buffer;
6955     bvci.format = VK_FORMAT_R8_UNORM;
6956     bvci.range = VK_WHOLE_SIZE;
6957
6958     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
6959     ASSERT_VK_SUCCESS(err);
6960
6961     VkWriteDescriptorSet descriptor_write = {};
6962     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6963     descriptor_write.dstSet = descriptor_set;
6964     descriptor_write.dstBinding = 0;
6965     descriptor_write.descriptorCount = 1;
6966     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6967     descriptor_write.pTexelBufferView = &view;
6968
6969     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6970
6971     char const *vsSource = "#version 450\n"
6972                            "\n"
6973                            "out gl_PerVertex { \n"
6974                            "    vec4 gl_Position;\n"
6975                            "};\n"
6976                            "void main(){\n"
6977                            "   gl_Position = vec4(1);\n"
6978                            "}\n";
6979     char const *fsSource = "#version 450\n"
6980                            "\n"
6981                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
6982                            "layout(location=0) out vec4 x;\n"
6983                            "void main(){\n"
6984                            "   x = imageLoad(s, 0);\n"
6985                            "}\n";
6986     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
6987     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6988     VkPipelineObj pipe(m_device);
6989     pipe.AddShader(&vs);
6990     pipe.AddShader(&fs);
6991     pipe.AddColorAttachment();
6992     pipe.CreateVKPipeline(pipeline_layout, renderPass());
6993
6994     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
6995     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
6996
6997     BeginCommandBuffer();
6998     VkViewport viewport = {0, 0, 16, 16, 0, 1};
6999     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
7000     VkRect2D scissor = {{0, 0}, {16, 16}};
7001     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
7002     // Bind pipeline to cmd buffer
7003     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7004     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7005                             &descriptor_set, 0, nullptr);
7006     Draw(1, 0, 0, 0);
7007     EndCommandBuffer();
7008
7009     // Delete BufferView in order to invalidate cmd buffer
7010     vkDestroyBufferView(m_device->device(), view, NULL);
7011     // Now attempt submit of cmd buffer
7012     VkSubmitInfo submit_info = {};
7013     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7014     submit_info.commandBufferCount = 1;
7015     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7016     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7017     m_errorMonitor->VerifyFound();
7018
7019     // Clean-up
7020     vkDestroyBuffer(m_device->device(), buffer, NULL);
7021     vkFreeMemory(m_device->device(), buffer_memory, NULL);
7022     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7023     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7024     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7025 }
7026
7027 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
7028     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7029                      "due to an image dependency being destroyed.");
7030     ASSERT_NO_FATAL_FAILURE(InitState());
7031
7032     VkImage image;
7033     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7034     VkImageCreateInfo image_create_info = {};
7035     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7036     image_create_info.pNext = NULL;
7037     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7038     image_create_info.format = tex_format;
7039     image_create_info.extent.width = 32;
7040     image_create_info.extent.height = 32;
7041     image_create_info.extent.depth = 1;
7042     image_create_info.mipLevels = 1;
7043     image_create_info.arrayLayers = 1;
7044     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7045     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7046     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7047     image_create_info.flags = 0;
7048     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7049     ASSERT_VK_SUCCESS(err);
7050     // Have to bind memory to image before recording cmd in cmd buffer using it
7051     VkMemoryRequirements mem_reqs;
7052     VkDeviceMemory image_mem;
7053     bool pass;
7054     VkMemoryAllocateInfo mem_alloc = {};
7055     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7056     mem_alloc.pNext = NULL;
7057     mem_alloc.memoryTypeIndex = 0;
7058     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7059     mem_alloc.allocationSize = mem_reqs.size;
7060     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7061     ASSERT_TRUE(pass);
7062     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7063     ASSERT_VK_SUCCESS(err);
7064     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
7065     ASSERT_VK_SUCCESS(err);
7066
7067     m_commandBuffer->BeginCommandBuffer();
7068     VkClearColorValue ccv;
7069     ccv.float32[0] = 1.0f;
7070     ccv.float32[1] = 1.0f;
7071     ccv.float32[2] = 1.0f;
7072     ccv.float32[3] = 1.0f;
7073     VkImageSubresourceRange isr = {};
7074     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7075     isr.baseArrayLayer = 0;
7076     isr.baseMipLevel = 0;
7077     isr.layerCount = 1;
7078     isr.levelCount = 1;
7079     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7080     m_commandBuffer->EndCommandBuffer();
7081
7082     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7083     // Destroy image dependency prior to submit to cause ERROR
7084     vkDestroyImage(m_device->device(), image, NULL);
7085
7086     VkSubmitInfo submit_info = {};
7087     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7088     submit_info.commandBufferCount = 1;
7089     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7090     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7091
7092     m_errorMonitor->VerifyFound();
7093     vkFreeMemory(m_device->device(), image_mem, nullptr);
7094 }
7095
7096 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
7097     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7098                      "due to a framebuffer image dependency being destroyed.");
7099     VkFormatProperties format_properties;
7100     VkResult err = VK_SUCCESS;
7101     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7102     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
7103         return;
7104     }
7105
7106     ASSERT_NO_FATAL_FAILURE(InitState());
7107     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7108
7109     VkImageCreateInfo image_ci = {};
7110     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7111     image_ci.pNext = NULL;
7112     image_ci.imageType = VK_IMAGE_TYPE_2D;
7113     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7114     image_ci.extent.width = 32;
7115     image_ci.extent.height = 32;
7116     image_ci.extent.depth = 1;
7117     image_ci.mipLevels = 1;
7118     image_ci.arrayLayers = 1;
7119     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7120     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7121     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7122     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7123     image_ci.flags = 0;
7124     VkImage image;
7125     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7126
7127     VkMemoryRequirements memory_reqs;
7128     VkDeviceMemory image_memory;
7129     bool pass;
7130     VkMemoryAllocateInfo memory_info = {};
7131     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7132     memory_info.pNext = NULL;
7133     memory_info.allocationSize = 0;
7134     memory_info.memoryTypeIndex = 0;
7135     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7136     memory_info.allocationSize = memory_reqs.size;
7137     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7138     ASSERT_TRUE(pass);
7139     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7140     ASSERT_VK_SUCCESS(err);
7141     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7142     ASSERT_VK_SUCCESS(err);
7143
7144     VkImageViewCreateInfo ivci = {
7145         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7146         nullptr,
7147         0,
7148         image,
7149         VK_IMAGE_VIEW_TYPE_2D,
7150         VK_FORMAT_B8G8R8A8_UNORM,
7151         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7152         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7153     };
7154     VkImageView view;
7155     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7156     ASSERT_VK_SUCCESS(err);
7157
7158     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
7159     VkFramebuffer fb;
7160     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7161     ASSERT_VK_SUCCESS(err);
7162
7163     // Just use default renderpass with our framebuffer
7164     m_renderPassBeginInfo.framebuffer = fb;
7165     // Create Null cmd buffer for submit
7166     BeginCommandBuffer();
7167     EndCommandBuffer();
7168     // Destroy image attached to framebuffer to invalidate cmd buffer
7169     vkDestroyImage(m_device->device(), image, NULL);
7170     // Now attempt to submit cmd buffer and verify error
7171     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7172     QueueCommandBuffer(false);
7173     m_errorMonitor->VerifyFound();
7174
7175     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7176     vkDestroyImageView(m_device->device(), view, nullptr);
7177     vkFreeMemory(m_device->device(), image_memory, nullptr);
7178 }
7179
7180 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
7181     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
7182     VkFormatProperties format_properties;
7183     VkResult err = VK_SUCCESS;
7184     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7185
7186     ASSERT_NO_FATAL_FAILURE(InitState());
7187     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7188
7189     VkImageCreateInfo image_ci = {};
7190     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7191     image_ci.pNext = NULL;
7192     image_ci.imageType = VK_IMAGE_TYPE_2D;
7193     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7194     image_ci.extent.width = 256;
7195     image_ci.extent.height = 256;
7196     image_ci.extent.depth = 1;
7197     image_ci.mipLevels = 1;
7198     image_ci.arrayLayers = 1;
7199     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7200     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7201     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
7202     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7203     image_ci.flags = 0;
7204     VkImage image;
7205     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7206
7207     VkMemoryRequirements memory_reqs;
7208     VkDeviceMemory image_memory;
7209     bool pass;
7210     VkMemoryAllocateInfo memory_info = {};
7211     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7212     memory_info.pNext = NULL;
7213     memory_info.allocationSize = 0;
7214     memory_info.memoryTypeIndex = 0;
7215     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7216     memory_info.allocationSize = memory_reqs.size;
7217     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7218     ASSERT_TRUE(pass);
7219     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7220     ASSERT_VK_SUCCESS(err);
7221     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7222     ASSERT_VK_SUCCESS(err);
7223
7224     VkImageViewCreateInfo ivci = {
7225         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7226         nullptr,
7227         0,
7228         image,
7229         VK_IMAGE_VIEW_TYPE_2D,
7230         VK_FORMAT_B8G8R8A8_UNORM,
7231         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7232         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7233     };
7234     VkImageView view;
7235     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7236     ASSERT_VK_SUCCESS(err);
7237
7238     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
7239     VkFramebuffer fb;
7240     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7241     ASSERT_VK_SUCCESS(err);
7242
7243     // Just use default renderpass with our framebuffer
7244     m_renderPassBeginInfo.framebuffer = fb;
7245     // Create Null cmd buffer for submit
7246     BeginCommandBuffer();
7247     EndCommandBuffer();
7248     // Submit cmd buffer to put it (and attached imageView) in-flight
7249     VkSubmitInfo submit_info = {};
7250     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7251     submit_info.commandBufferCount = 1;
7252     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7253     // Submit cmd buffer to put framebuffer and children in-flight
7254     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7255     // Destroy image attached to framebuffer while in-flight
7256     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
7257     vkDestroyImage(m_device->device(), image, NULL);
7258     m_errorMonitor->VerifyFound();
7259     // Wait for queue to complete so we can safely destroy image and other objects
7260     vkQueueWaitIdle(m_device->m_queue);
7261     vkDestroyImage(m_device->device(), image, NULL);
7262     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7263     vkDestroyImageView(m_device->device(), view, nullptr);
7264     vkFreeMemory(m_device->device(), image_memory, nullptr);
7265 }
7266
7267 TEST_F(VkLayerTest, ImageMemoryNotBound) {
7268     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
7269     ASSERT_NO_FATAL_FAILURE(InitState());
7270
7271     VkImage image;
7272     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7273     VkImageCreateInfo image_create_info = {};
7274     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7275     image_create_info.pNext = NULL;
7276     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7277     image_create_info.format = tex_format;
7278     image_create_info.extent.width = 32;
7279     image_create_info.extent.height = 32;
7280     image_create_info.extent.depth = 1;
7281     image_create_info.mipLevels = 1;
7282     image_create_info.arrayLayers = 1;
7283     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7284     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7285     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7286     image_create_info.flags = 0;
7287     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7288     ASSERT_VK_SUCCESS(err);
7289     // Have to bind memory to image before recording cmd in cmd buffer using it
7290     VkMemoryRequirements mem_reqs;
7291     VkDeviceMemory image_mem;
7292     bool pass;
7293     VkMemoryAllocateInfo mem_alloc = {};
7294     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7295     mem_alloc.pNext = NULL;
7296     mem_alloc.memoryTypeIndex = 0;
7297     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7298     mem_alloc.allocationSize = mem_reqs.size;
7299     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7300     ASSERT_TRUE(pass);
7301     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7302     ASSERT_VK_SUCCESS(err);
7303
7304     // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
7305     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7306                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
7307
7308     m_commandBuffer->BeginCommandBuffer();
7309     VkClearColorValue ccv;
7310     ccv.float32[0] = 1.0f;
7311     ccv.float32[1] = 1.0f;
7312     ccv.float32[2] = 1.0f;
7313     ccv.float32[3] = 1.0f;
7314     VkImageSubresourceRange isr = {};
7315     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7316     isr.baseArrayLayer = 0;
7317     isr.baseMipLevel = 0;
7318     isr.layerCount = 1;
7319     isr.levelCount = 1;
7320     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7321     m_commandBuffer->EndCommandBuffer();
7322
7323     m_errorMonitor->VerifyFound();
7324     vkDestroyImage(m_device->device(), image, NULL);
7325     vkFreeMemory(m_device->device(), image_mem, nullptr);
7326 }
7327
7328 TEST_F(VkLayerTest, BufferMemoryNotBound) {
7329     TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
7330     ASSERT_NO_FATAL_FAILURE(InitState());
7331
7332     VkImageObj image(m_device);
7333     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7334                VK_IMAGE_TILING_OPTIMAL, 0);
7335     ASSERT_TRUE(image.initialized());
7336
7337     VkBuffer buffer;
7338     VkDeviceMemory mem;
7339     VkMemoryRequirements mem_reqs;
7340
7341     VkBufferCreateInfo buf_info = {};
7342     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7343     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
7344     buf_info.size = 256;
7345     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7346     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
7347     ASSERT_VK_SUCCESS(err);
7348
7349     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
7350
7351     VkMemoryAllocateInfo alloc_info = {};
7352     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7353     alloc_info.allocationSize = 256;
7354     bool pass = false;
7355     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
7356     if (!pass) {
7357         vkDestroyBuffer(m_device->device(), buffer, NULL);
7358         return;
7359     }
7360     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
7361     ASSERT_VK_SUCCESS(err);
7362
7363     // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7364     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7365                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
7366     VkBufferImageCopy region = {};
7367     region.bufferRowLength = 128;
7368     region.bufferImageHeight = 128;
7369     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7370
7371     region.imageSubresource.layerCount = 1;
7372     region.imageExtent.height = 4;
7373     region.imageExtent.width = 4;
7374     region.imageExtent.depth = 1;
7375     m_commandBuffer->BeginCommandBuffer();
7376     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7377                            &region);
7378     m_commandBuffer->EndCommandBuffer();
7379
7380     m_errorMonitor->VerifyFound();
7381
7382     vkDestroyBuffer(m_device->device(), buffer, NULL);
7383     vkFreeMemory(m_device->handle(), mem, NULL);
7384 }
7385
7386 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
7387     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7388                      "due to an event dependency being destroyed.");
7389     ASSERT_NO_FATAL_FAILURE(InitState());
7390
7391     VkEvent event;
7392     VkEventCreateInfo evci = {};
7393     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
7394     VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
7395     ASSERT_VK_SUCCESS(result);
7396
7397     m_commandBuffer->BeginCommandBuffer();
7398     vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7399     m_commandBuffer->EndCommandBuffer();
7400
7401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
7402     // Destroy event dependency prior to submit to cause ERROR
7403     vkDestroyEvent(m_device->device(), event, NULL);
7404
7405     VkSubmitInfo submit_info = {};
7406     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7407     submit_info.commandBufferCount = 1;
7408     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7409     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7410
7411     m_errorMonitor->VerifyFound();
7412 }
7413
7414 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
7415     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7416                      "due to a query pool dependency being destroyed.");
7417     ASSERT_NO_FATAL_FAILURE(InitState());
7418
7419     VkQueryPool query_pool;
7420     VkQueryPoolCreateInfo qpci{};
7421     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7422     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
7423     qpci.queryCount = 1;
7424     VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
7425     ASSERT_VK_SUCCESS(result);
7426
7427     m_commandBuffer->BeginCommandBuffer();
7428     vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
7429     m_commandBuffer->EndCommandBuffer();
7430
7431     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool ");
7432     // Destroy query pool dependency prior to submit to cause ERROR
7433     vkDestroyQueryPool(m_device->device(), query_pool, NULL);
7434
7435     VkSubmitInfo submit_info = {};
7436     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7437     submit_info.commandBufferCount = 1;
7438     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7439     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7440
7441     m_errorMonitor->VerifyFound();
7442 }
7443
7444 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
7445     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7446                      "due to a pipeline dependency being destroyed.");
7447     ASSERT_NO_FATAL_FAILURE(InitState());
7448     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7449
7450     VkResult err;
7451
7452     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7453     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7454
7455     VkPipelineLayout pipeline_layout;
7456     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7457     ASSERT_VK_SUCCESS(err);
7458
7459     VkPipelineViewportStateCreateInfo vp_state_ci = {};
7460     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7461     vp_state_ci.viewportCount = 1;
7462     VkViewport vp = {}; // Just need dummy vp to point to
7463     vp_state_ci.pViewports = &vp;
7464     vp_state_ci.scissorCount = 1;
7465     VkRect2D scissors = {}; // Dummy scissors to point to
7466     vp_state_ci.pScissors = &scissors;
7467
7468     VkPipelineShaderStageCreateInfo shaderStages[2];
7469     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
7470
7471     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7472     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
7473     // but add it to be able to run on more devices
7474     shaderStages[0] = vs.GetStageCreateInfo();
7475     shaderStages[1] = fs.GetStageCreateInfo();
7476
7477     VkPipelineVertexInputStateCreateInfo vi_ci = {};
7478     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7479
7480     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
7481     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7482     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
7483
7484     VkPipelineRasterizationStateCreateInfo rs_ci = {};
7485     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7486     rs_ci.rasterizerDiscardEnable = true;
7487     rs_ci.lineWidth = 1.0f;
7488
7489     VkPipelineColorBlendAttachmentState att = {};
7490     att.blendEnable = VK_FALSE;
7491     att.colorWriteMask = 0xf;
7492
7493     VkPipelineColorBlendStateCreateInfo cb_ci = {};
7494     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7495     cb_ci.attachmentCount = 1;
7496     cb_ci.pAttachments = &att;
7497
7498     VkGraphicsPipelineCreateInfo gp_ci = {};
7499     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7500     gp_ci.stageCount = 2;
7501     gp_ci.pStages = shaderStages;
7502     gp_ci.pVertexInputState = &vi_ci;
7503     gp_ci.pInputAssemblyState = &ia_ci;
7504     gp_ci.pViewportState = &vp_state_ci;
7505     gp_ci.pRasterizationState = &rs_ci;
7506     gp_ci.pColorBlendState = &cb_ci;
7507     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
7508     gp_ci.layout = pipeline_layout;
7509     gp_ci.renderPass = renderPass();
7510
7511     VkPipelineCacheCreateInfo pc_ci = {};
7512     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
7513
7514     VkPipeline pipeline;
7515     VkPipelineCache pipelineCache;
7516     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
7517     ASSERT_VK_SUCCESS(err);
7518
7519     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
7520     ASSERT_VK_SUCCESS(err);
7521
7522     m_commandBuffer->BeginCommandBuffer();
7523     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
7524     m_commandBuffer->EndCommandBuffer();
7525     // Now destroy pipeline in order to cause error when submitting
7526     vkDestroyPipeline(m_device->device(), pipeline, nullptr);
7527
7528     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline ");
7529
7530     VkSubmitInfo submit_info = {};
7531     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7532     submit_info.commandBufferCount = 1;
7533     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7534     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7535
7536     m_errorMonitor->VerifyFound();
7537     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
7538     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7539 }
7540
7541 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
7542     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7543                      "due to a bound descriptor set with a buffer dependency "
7544                      "being destroyed.");
7545     ASSERT_NO_FATAL_FAILURE(InitState());
7546     ASSERT_NO_FATAL_FAILURE(InitViewport());
7547     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7548
7549     VkDescriptorPoolSize ds_type_count = {};
7550     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7551     ds_type_count.descriptorCount = 1;
7552
7553     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7554     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7555     ds_pool_ci.pNext = NULL;
7556     ds_pool_ci.maxSets = 1;
7557     ds_pool_ci.poolSizeCount = 1;
7558     ds_pool_ci.pPoolSizes = &ds_type_count;
7559
7560     VkDescriptorPool ds_pool;
7561     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7562     ASSERT_VK_SUCCESS(err);
7563
7564     VkDescriptorSetLayoutBinding dsl_binding = {};
7565     dsl_binding.binding = 0;
7566     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7567     dsl_binding.descriptorCount = 1;
7568     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7569     dsl_binding.pImmutableSamplers = NULL;
7570
7571     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7572     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7573     ds_layout_ci.pNext = NULL;
7574     ds_layout_ci.bindingCount = 1;
7575     ds_layout_ci.pBindings = &dsl_binding;
7576     VkDescriptorSetLayout ds_layout;
7577     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7578     ASSERT_VK_SUCCESS(err);
7579
7580     VkDescriptorSet descriptorSet;
7581     VkDescriptorSetAllocateInfo alloc_info = {};
7582     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7583     alloc_info.descriptorSetCount = 1;
7584     alloc_info.descriptorPool = ds_pool;
7585     alloc_info.pSetLayouts = &ds_layout;
7586     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7587     ASSERT_VK_SUCCESS(err);
7588
7589     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7590     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7591     pipeline_layout_ci.pNext = NULL;
7592     pipeline_layout_ci.setLayoutCount = 1;
7593     pipeline_layout_ci.pSetLayouts = &ds_layout;
7594
7595     VkPipelineLayout pipeline_layout;
7596     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7597     ASSERT_VK_SUCCESS(err);
7598
7599     // Create a buffer to update the descriptor with
7600     uint32_t qfi = 0;
7601     VkBufferCreateInfo buffCI = {};
7602     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7603     buffCI.size = 1024;
7604     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
7605     buffCI.queueFamilyIndexCount = 1;
7606     buffCI.pQueueFamilyIndices = &qfi;
7607
7608     VkBuffer buffer;
7609     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
7610     ASSERT_VK_SUCCESS(err);
7611     // Allocate memory and bind to buffer so we can make it to the appropriate
7612     // error
7613     VkMemoryAllocateInfo mem_alloc = {};
7614     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7615     mem_alloc.pNext = NULL;
7616     mem_alloc.allocationSize = 1024;
7617     mem_alloc.memoryTypeIndex = 0;
7618
7619     VkMemoryRequirements memReqs;
7620     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
7621     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
7622     if (!pass) {
7623         vkDestroyBuffer(m_device->device(), buffer, NULL);
7624         return;
7625     }
7626
7627     VkDeviceMemory mem;
7628     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
7629     ASSERT_VK_SUCCESS(err);
7630     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7631     ASSERT_VK_SUCCESS(err);
7632     // Correctly update descriptor to avoid "NOT_UPDATED" error
7633     VkDescriptorBufferInfo buffInfo = {};
7634     buffInfo.buffer = buffer;
7635     buffInfo.offset = 0;
7636     buffInfo.range = 1024;
7637
7638     VkWriteDescriptorSet descriptor_write;
7639     memset(&descriptor_write, 0, sizeof(descriptor_write));
7640     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7641     descriptor_write.dstSet = descriptorSet;
7642     descriptor_write.dstBinding = 0;
7643     descriptor_write.descriptorCount = 1;
7644     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7645     descriptor_write.pBufferInfo = &buffInfo;
7646
7647     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7648
7649     // Create PSO to be used for draw-time errors below
7650     char const *vsSource = "#version 450\n"
7651                            "\n"
7652                            "out gl_PerVertex { \n"
7653                            "    vec4 gl_Position;\n"
7654                            "};\n"
7655                            "void main(){\n"
7656                            "   gl_Position = vec4(1);\n"
7657                            "}\n";
7658     char const *fsSource = "#version 450\n"
7659                            "\n"
7660                            "layout(location=0) out vec4 x;\n"
7661                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
7662                            "void main(){\n"
7663                            "   x = vec4(bar.y);\n"
7664                            "}\n";
7665     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7666     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7667     VkPipelineObj pipe(m_device);
7668     pipe.AddShader(&vs);
7669     pipe.AddShader(&fs);
7670     pipe.AddColorAttachment();
7671     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7672
7673     BeginCommandBuffer();
7674     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7675     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7676                             &descriptorSet, 0, NULL);
7677     Draw(1, 0, 0, 0);
7678     EndCommandBuffer();
7679     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
7680     // Destroy buffer should invalidate the cmd buffer, causing error on submit
7681     vkDestroyBuffer(m_device->device(), buffer, NULL);
7682     // Attempt to submit cmd buffer
7683     VkSubmitInfo submit_info = {};
7684     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7685     submit_info.commandBufferCount = 1;
7686     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7687     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7688     m_errorMonitor->VerifyFound();
7689     // Cleanup
7690     vkFreeMemory(m_device->device(), mem, NULL);
7691
7692     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7693     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7694     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7695 }
7696
7697 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
7698     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7699                      "due to a bound descriptor sets with a combined image "
7700                      "sampler having their image, sampler, and descriptor set "
7701                      "each respectively destroyed and then attempting to "
7702                      "submit associated cmd buffers. Attempt to destroy a "
7703                      "DescriptorSet that is in use.");
7704     ASSERT_NO_FATAL_FAILURE(InitState());
7705     ASSERT_NO_FATAL_FAILURE(InitViewport());
7706     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7707
7708     VkDescriptorPoolSize ds_type_count = {};
7709     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7710     ds_type_count.descriptorCount = 1;
7711
7712     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7713     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7714     ds_pool_ci.pNext = NULL;
7715     ds_pool_ci.maxSets = 1;
7716     ds_pool_ci.poolSizeCount = 1;
7717     ds_pool_ci.pPoolSizes = &ds_type_count;
7718
7719     VkDescriptorPool ds_pool;
7720     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7721     ASSERT_VK_SUCCESS(err);
7722
7723     VkDescriptorSetLayoutBinding dsl_binding = {};
7724     dsl_binding.binding = 0;
7725     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7726     dsl_binding.descriptorCount = 1;
7727     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7728     dsl_binding.pImmutableSamplers = NULL;
7729
7730     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7731     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7732     ds_layout_ci.pNext = NULL;
7733     ds_layout_ci.bindingCount = 1;
7734     ds_layout_ci.pBindings = &dsl_binding;
7735     VkDescriptorSetLayout ds_layout;
7736     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7737     ASSERT_VK_SUCCESS(err);
7738
7739     VkDescriptorSet descriptorSet;
7740     VkDescriptorSetAllocateInfo alloc_info = {};
7741     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7742     alloc_info.descriptorSetCount = 1;
7743     alloc_info.descriptorPool = ds_pool;
7744     alloc_info.pSetLayouts = &ds_layout;
7745     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7746     ASSERT_VK_SUCCESS(err);
7747
7748     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7749     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7750     pipeline_layout_ci.pNext = NULL;
7751     pipeline_layout_ci.setLayoutCount = 1;
7752     pipeline_layout_ci.pSetLayouts = &ds_layout;
7753
7754     VkPipelineLayout pipeline_layout;
7755     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7756     ASSERT_VK_SUCCESS(err);
7757
7758     // Create images to update the descriptor with
7759     VkImage image;
7760     VkImage image2;
7761     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7762     const int32_t tex_width = 32;
7763     const int32_t tex_height = 32;
7764     VkImageCreateInfo image_create_info = {};
7765     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7766     image_create_info.pNext = NULL;
7767     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7768     image_create_info.format = tex_format;
7769     image_create_info.extent.width = tex_width;
7770     image_create_info.extent.height = tex_height;
7771     image_create_info.extent.depth = 1;
7772     image_create_info.mipLevels = 1;
7773     image_create_info.arrayLayers = 1;
7774     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7775     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7776     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
7777     image_create_info.flags = 0;
7778     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7779     ASSERT_VK_SUCCESS(err);
7780     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
7781     ASSERT_VK_SUCCESS(err);
7782
7783     VkMemoryRequirements memory_reqs;
7784     VkDeviceMemory image_memory;
7785     bool pass;
7786     VkMemoryAllocateInfo memory_info = {};
7787     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7788     memory_info.pNext = NULL;
7789     memory_info.allocationSize = 0;
7790     memory_info.memoryTypeIndex = 0;
7791     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7792     // Allocate enough memory for both images
7793     memory_info.allocationSize = memory_reqs.size * 2;
7794     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7795     ASSERT_TRUE(pass);
7796     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7797     ASSERT_VK_SUCCESS(err);
7798     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7799     ASSERT_VK_SUCCESS(err);
7800     // Bind second image to memory right after first image
7801     err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
7802     ASSERT_VK_SUCCESS(err);
7803
7804     VkImageViewCreateInfo image_view_create_info = {};
7805     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7806     image_view_create_info.image = image;
7807     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
7808     image_view_create_info.format = tex_format;
7809     image_view_create_info.subresourceRange.layerCount = 1;
7810     image_view_create_info.subresourceRange.baseMipLevel = 0;
7811     image_view_create_info.subresourceRange.levelCount = 1;
7812     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7813
7814     VkImageView view;
7815     VkImageView view2;
7816     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
7817     ASSERT_VK_SUCCESS(err);
7818     image_view_create_info.image = image2;
7819     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
7820     ASSERT_VK_SUCCESS(err);
7821     // Create Samplers
7822     VkSamplerCreateInfo sampler_ci = {};
7823     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
7824     sampler_ci.pNext = NULL;
7825     sampler_ci.magFilter = VK_FILTER_NEAREST;
7826     sampler_ci.minFilter = VK_FILTER_NEAREST;
7827     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
7828     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7829     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7830     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7831     sampler_ci.mipLodBias = 1.0;
7832     sampler_ci.anisotropyEnable = VK_FALSE;
7833     sampler_ci.maxAnisotropy = 1;
7834     sampler_ci.compareEnable = VK_FALSE;
7835     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
7836     sampler_ci.minLod = 1.0;
7837     sampler_ci.maxLod = 1.0;
7838     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
7839     sampler_ci.unnormalizedCoordinates = VK_FALSE;
7840     VkSampler sampler;
7841     VkSampler sampler2;
7842     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7843     ASSERT_VK_SUCCESS(err);
7844     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
7845     ASSERT_VK_SUCCESS(err);
7846     // Update descriptor with image and sampler
7847     VkDescriptorImageInfo img_info = {};
7848     img_info.sampler = sampler;
7849     img_info.imageView = view;
7850     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7851
7852     VkWriteDescriptorSet descriptor_write;
7853     memset(&descriptor_write, 0, sizeof(descriptor_write));
7854     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7855     descriptor_write.dstSet = descriptorSet;
7856     descriptor_write.dstBinding = 0;
7857     descriptor_write.descriptorCount = 1;
7858     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7859     descriptor_write.pImageInfo = &img_info;
7860
7861     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7862
7863     // Create PSO to be used for draw-time errors below
7864     char const *vsSource = "#version 450\n"
7865                            "\n"
7866                            "out gl_PerVertex { \n"
7867                            "    vec4 gl_Position;\n"
7868                            "};\n"
7869                            "void main(){\n"
7870                            "   gl_Position = vec4(1);\n"
7871                            "}\n";
7872     char const *fsSource = "#version 450\n"
7873                            "\n"
7874                            "layout(set=0, binding=0) uniform sampler2D s;\n"
7875                            "layout(location=0) out vec4 x;\n"
7876                            "void main(){\n"
7877                            "   x = texture(s, vec2(1));\n"
7878                            "}\n";
7879     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7880     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7881     VkPipelineObj pipe(m_device);
7882     pipe.AddShader(&vs);
7883     pipe.AddShader(&fs);
7884     pipe.AddColorAttachment();
7885     pipe.CreateVKPipeline(pipeline_layout, renderPass());
7886
7887     // First error case is destroying sampler prior to cmd buffer submission
7888     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler ");
7889     BeginCommandBuffer();
7890     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7891     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7892                             &descriptorSet, 0, NULL);
7893     Draw(1, 0, 0, 0);
7894     EndCommandBuffer();
7895     // Destroy sampler invalidates the cmd buffer, causing error on submit
7896     vkDestroySampler(m_device->device(), sampler, NULL);
7897     // Attempt to submit cmd buffer
7898     VkSubmitInfo submit_info = {};
7899     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7900     submit_info.commandBufferCount = 1;
7901     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7902     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7903     m_errorMonitor->VerifyFound();
7904     // Now re-update descriptor with valid sampler and delete image
7905     img_info.sampler = sampler2;
7906     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7907     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7908     BeginCommandBuffer();
7909     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7910     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7911                             &descriptorSet, 0, NULL);
7912     Draw(1, 0, 0, 0);
7913     EndCommandBuffer();
7914     // Destroy image invalidates the cmd buffer, causing error on submit
7915     vkDestroyImage(m_device->device(), image, NULL);
7916     // Attempt to submit cmd buffer
7917     submit_info = {};
7918     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7919     submit_info.commandBufferCount = 1;
7920     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7921     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7922     m_errorMonitor->VerifyFound();
7923     // Now update descriptor to be valid, but then free descriptor
7924     img_info.imageView = view2;
7925     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7926     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set ");
7927     BeginCommandBuffer();
7928     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7929     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7930                             &descriptorSet, 0, NULL);
7931     Draw(1, 0, 0, 0);
7932     EndCommandBuffer();
7933     // Destroy descriptor set invalidates the cb, causing error on submit
7934     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
7935     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
7936     m_errorMonitor->VerifyFound();
7937     // Attempt to submit cmd buffer
7938     submit_info = {};
7939     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7940     submit_info.commandBufferCount = 1;
7941     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7942     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7943     m_errorMonitor->VerifyFound();
7944     // Cleanup
7945     vkFreeMemory(m_device->device(), image_memory, NULL);
7946     vkDestroySampler(m_device->device(), sampler2, NULL);
7947     vkDestroyImage(m_device->device(), image2, NULL);
7948     vkDestroyImageView(m_device->device(), view, NULL);
7949     vkDestroyImageView(m_device->device(), view2, NULL);
7950     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7951     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7952     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7953 }
7954
7955 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
7956     TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
7957     ASSERT_NO_FATAL_FAILURE(InitState());
7958     ASSERT_NO_FATAL_FAILURE(InitViewport());
7959     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7960
7961     VkDescriptorPoolSize ds_type_count = {};
7962     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7963     ds_type_count.descriptorCount = 1;
7964
7965     VkDescriptorPoolCreateInfo ds_pool_ci = {};
7966     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7967     ds_pool_ci.pNext = NULL;
7968     ds_pool_ci.maxSets = 1;
7969     ds_pool_ci.poolSizeCount = 1;
7970     ds_pool_ci.pPoolSizes = &ds_type_count;
7971
7972     VkDescriptorPool ds_pool;
7973     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7974     ASSERT_VK_SUCCESS(err);
7975
7976     VkDescriptorSetLayoutBinding dsl_binding = {};
7977     dsl_binding.binding = 0;
7978     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7979     dsl_binding.descriptorCount = 1;
7980     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7981     dsl_binding.pImmutableSamplers = NULL;
7982
7983     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7984     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7985     ds_layout_ci.pNext = NULL;
7986     ds_layout_ci.bindingCount = 1;
7987     ds_layout_ci.pBindings = &dsl_binding;
7988     VkDescriptorSetLayout ds_layout;
7989     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7990     ASSERT_VK_SUCCESS(err);
7991
7992     VkDescriptorSet descriptorSet;
7993     VkDescriptorSetAllocateInfo alloc_info = {};
7994     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7995     alloc_info.descriptorSetCount = 1;
7996     alloc_info.descriptorPool = ds_pool;
7997     alloc_info.pSetLayouts = &ds_layout;
7998     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7999     ASSERT_VK_SUCCESS(err);
8000
8001     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8002     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8003     pipeline_layout_ci.pNext = NULL;
8004     pipeline_layout_ci.setLayoutCount = 1;
8005     pipeline_layout_ci.pSetLayouts = &ds_layout;
8006
8007     VkPipelineLayout pipeline_layout;
8008     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8009     ASSERT_VK_SUCCESS(err);
8010
8011     // Create images to update the descriptor with
8012     VkImage image;
8013     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8014     const int32_t tex_width = 32;
8015     const int32_t tex_height = 32;
8016     VkImageCreateInfo image_create_info = {};
8017     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8018     image_create_info.pNext = NULL;
8019     image_create_info.imageType = VK_IMAGE_TYPE_2D;
8020     image_create_info.format = tex_format;
8021     image_create_info.extent.width = tex_width;
8022     image_create_info.extent.height = tex_height;
8023     image_create_info.extent.depth = 1;
8024     image_create_info.mipLevels = 1;
8025     image_create_info.arrayLayers = 1;
8026     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
8027     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
8028     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8029     image_create_info.flags = 0;
8030     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
8031     ASSERT_VK_SUCCESS(err);
8032     // Initially bind memory to avoid error at bind view time. We'll break binding before update.
8033     VkMemoryRequirements memory_reqs;
8034     VkDeviceMemory image_memory;
8035     bool pass;
8036     VkMemoryAllocateInfo memory_info = {};
8037     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8038     memory_info.pNext = NULL;
8039     memory_info.allocationSize = 0;
8040     memory_info.memoryTypeIndex = 0;
8041     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
8042     // Allocate enough memory for image
8043     memory_info.allocationSize = memory_reqs.size;
8044     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
8045     ASSERT_TRUE(pass);
8046     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
8047     ASSERT_VK_SUCCESS(err);
8048     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
8049     ASSERT_VK_SUCCESS(err);
8050
8051     VkImageViewCreateInfo image_view_create_info = {};
8052     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8053     image_view_create_info.image = image;
8054     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
8055     image_view_create_info.format = tex_format;
8056     image_view_create_info.subresourceRange.layerCount = 1;
8057     image_view_create_info.subresourceRange.baseMipLevel = 0;
8058     image_view_create_info.subresourceRange.levelCount = 1;
8059     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8060
8061     VkImageView view;
8062     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
8063     ASSERT_VK_SUCCESS(err);
8064     // Create Samplers
8065     VkSamplerCreateInfo sampler_ci = {};
8066     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
8067     sampler_ci.pNext = NULL;
8068     sampler_ci.magFilter = VK_FILTER_NEAREST;
8069     sampler_ci.minFilter = VK_FILTER_NEAREST;
8070     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
8071     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8072     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8073     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8074     sampler_ci.mipLodBias = 1.0;
8075     sampler_ci.anisotropyEnable = VK_FALSE;
8076     sampler_ci.maxAnisotropy = 1;
8077     sampler_ci.compareEnable = VK_FALSE;
8078     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
8079     sampler_ci.minLod = 1.0;
8080     sampler_ci.maxLod = 1.0;
8081     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
8082     sampler_ci.unnormalizedCoordinates = VK_FALSE;
8083     VkSampler sampler;
8084     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8085     ASSERT_VK_SUCCESS(err);
8086     // Update descriptor with image and sampler
8087     VkDescriptorImageInfo img_info = {};
8088     img_info.sampler = sampler;
8089     img_info.imageView = view;
8090     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8091
8092     VkWriteDescriptorSet descriptor_write;
8093     memset(&descriptor_write, 0, sizeof(descriptor_write));
8094     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8095     descriptor_write.dstSet = descriptorSet;
8096     descriptor_write.dstBinding = 0;
8097     descriptor_write.descriptorCount = 1;
8098     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8099     descriptor_write.pImageInfo = &img_info;
8100     // Break memory binding and attempt update
8101     vkFreeMemory(m_device->device(), image_memory, nullptr);
8102     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8103                                          " previously bound memory was freed. Memory must not be freed prior to this operation.");
8104     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8105                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8106     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8107     m_errorMonitor->VerifyFound();
8108     // Cleanup
8109     vkDestroyImage(m_device->device(), image, NULL);
8110     vkDestroySampler(m_device->device(), sampler, NULL);
8111     vkDestroyImageView(m_device->device(), view, NULL);
8112     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8113     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8114     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8115 }
8116
8117 TEST_F(VkLayerTest, InvalidPipeline) {
8118     // Attempt to bind an invalid Pipeline to a valid Command Buffer
8119     // ObjectTracker should catch this.
8120     // Create a valid cmd buffer
8121     // call vkCmdBindPipeline w/ false Pipeline
8122     uint64_t fake_pipeline_handle = 0xbaad6001;
8123     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
8124     ASSERT_NO_FATAL_FAILURE(InitState());
8125     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8126
8127     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
8128     BeginCommandBuffer();
8129     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
8130     m_errorMonitor->VerifyFound();
8131
8132     // Now issue a draw call with no pipeline bound
8133     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8134     Draw(1, 0, 0, 0);
8135     m_errorMonitor->VerifyFound();
8136
8137     // Finally same check once more but with Dispatch/Compute
8138     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8139     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
8140     vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
8141     m_errorMonitor->VerifyFound();
8142 }
8143
8144 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
8145     TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
8146     VkResult err;
8147
8148     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
8149
8150     ASSERT_NO_FATAL_FAILURE(InitState());
8151     ASSERT_NO_FATAL_FAILURE(InitViewport());
8152     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8153     VkDescriptorPoolSize ds_type_count = {};
8154     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8155     ds_type_count.descriptorCount = 1;
8156
8157     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8158     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8159     ds_pool_ci.pNext = NULL;
8160     ds_pool_ci.maxSets = 1;
8161     ds_pool_ci.poolSizeCount = 1;
8162     ds_pool_ci.pPoolSizes = &ds_type_count;
8163
8164     VkDescriptorPool ds_pool;
8165     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8166     ASSERT_VK_SUCCESS(err);
8167
8168     VkDescriptorSetLayoutBinding dsl_binding = {};
8169     dsl_binding.binding = 0;
8170     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8171     dsl_binding.descriptorCount = 1;
8172     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8173     dsl_binding.pImmutableSamplers = NULL;
8174
8175     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8176     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8177     ds_layout_ci.pNext = NULL;
8178     ds_layout_ci.bindingCount = 1;
8179     ds_layout_ci.pBindings = &dsl_binding;
8180     VkDescriptorSetLayout ds_layout;
8181     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8182     ASSERT_VK_SUCCESS(err);
8183
8184     VkDescriptorSet descriptorSet;
8185     VkDescriptorSetAllocateInfo alloc_info = {};
8186     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8187     alloc_info.descriptorSetCount = 1;
8188     alloc_info.descriptorPool = ds_pool;
8189     alloc_info.pSetLayouts = &ds_layout;
8190     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8191     ASSERT_VK_SUCCESS(err);
8192
8193     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8194     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8195     pipeline_layout_ci.pNext = NULL;
8196     pipeline_layout_ci.setLayoutCount = 1;
8197     pipeline_layout_ci.pSetLayouts = &ds_layout;
8198
8199     VkPipelineLayout pipeline_layout;
8200     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8201     ASSERT_VK_SUCCESS(err);
8202
8203     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8204     //  We shouldn't need a fragment shader but add it to be able to run
8205     //  on more devices
8206     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8207
8208     VkPipelineObj pipe(m_device);
8209     pipe.AddShader(&vs);
8210     pipe.AddShader(&fs);
8211     pipe.AddColorAttachment();
8212     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8213
8214     BeginCommandBuffer();
8215     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8216     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8217                             &descriptorSet, 0, NULL);
8218
8219     m_errorMonitor->VerifyFound();
8220
8221     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8222     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8223     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8224 }
8225
8226 TEST_F(VkLayerTest, InvalidBufferViewObject) {
8227     // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
8228     VkResult err;
8229
8230     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer "
8231                                                                         "descriptor with invalid buffer view");
8232
8233     ASSERT_NO_FATAL_FAILURE(InitState());
8234     VkDescriptorPoolSize ds_type_count = {};
8235     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8236     ds_type_count.descriptorCount = 1;
8237
8238     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8239     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8240     ds_pool_ci.pNext = NULL;
8241     ds_pool_ci.maxSets = 1;
8242     ds_pool_ci.poolSizeCount = 1;
8243     ds_pool_ci.pPoolSizes = &ds_type_count;
8244
8245     VkDescriptorPool ds_pool;
8246     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8247     ASSERT_VK_SUCCESS(err);
8248
8249     VkDescriptorSetLayoutBinding dsl_binding = {};
8250     dsl_binding.binding = 0;
8251     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8252     dsl_binding.descriptorCount = 1;
8253     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8254     dsl_binding.pImmutableSamplers = NULL;
8255
8256     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8257     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8258     ds_layout_ci.pNext = NULL;
8259     ds_layout_ci.bindingCount = 1;
8260     ds_layout_ci.pBindings = &dsl_binding;
8261     VkDescriptorSetLayout ds_layout;
8262     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8263     ASSERT_VK_SUCCESS(err);
8264
8265     VkDescriptorSet descriptorSet;
8266     VkDescriptorSetAllocateInfo alloc_info = {};
8267     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8268     alloc_info.descriptorSetCount = 1;
8269     alloc_info.descriptorPool = ds_pool;
8270     alloc_info.pSetLayouts = &ds_layout;
8271     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8272     ASSERT_VK_SUCCESS(err);
8273
8274     VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object
8275     VkWriteDescriptorSet descriptor_write;
8276     memset(&descriptor_write, 0, sizeof(descriptor_write));
8277     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8278     descriptor_write.dstSet = descriptorSet;
8279     descriptor_write.dstBinding = 0;
8280     descriptor_write.descriptorCount = 1;
8281     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8282     descriptor_write.pTexelBufferView = &view;
8283
8284     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8285
8286     m_errorMonitor->VerifyFound();
8287
8288     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8289     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8290 }
8291
8292 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
8293     TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
8294
8295     VkResult err;
8296     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8297                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8298
8299     ASSERT_NO_FATAL_FAILURE(InitState());
8300
8301     // Create a buffer with no bound memory and then attempt to create
8302     // a buffer view.
8303     VkBufferCreateInfo buff_ci = {};
8304     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8305     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
8306     buff_ci.size = 256;
8307     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8308     VkBuffer buffer;
8309     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
8310     ASSERT_VK_SUCCESS(err);
8311
8312     VkBufferViewCreateInfo buff_view_ci = {};
8313     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8314     buff_view_ci.buffer = buffer;
8315     buff_view_ci.format = VK_FORMAT_R8_UNORM;
8316     buff_view_ci.range = VK_WHOLE_SIZE;
8317     VkBufferView buff_view;
8318     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
8319
8320     m_errorMonitor->VerifyFound();
8321     vkDestroyBuffer(m_device->device(), buffer, NULL);
8322     // If last error is success, it still created the view, so delete it.
8323     if (err == VK_SUCCESS) {
8324         vkDestroyBufferView(m_device->device(), buff_view, NULL);
8325     }
8326 }
8327
8328 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
8329     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
8330     // cases:
8331     // 1. No dynamicOffset supplied
8332     // 2. Too many dynamicOffsets supplied
8333     // 3. Dynamic offset oversteps buffer being updated
8334     VkResult err;
8335     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only "
8336                                                                         "0 dynamicOffsets are left in "
8337                                                                         "pDynamicOffsets ");
8338
8339     ASSERT_NO_FATAL_FAILURE(InitState());
8340     ASSERT_NO_FATAL_FAILURE(InitViewport());
8341     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8342
8343     VkDescriptorPoolSize ds_type_count = {};
8344     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8345     ds_type_count.descriptorCount = 1;
8346
8347     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8348     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8349     ds_pool_ci.pNext = NULL;
8350     ds_pool_ci.maxSets = 1;
8351     ds_pool_ci.poolSizeCount = 1;
8352     ds_pool_ci.pPoolSizes = &ds_type_count;
8353
8354     VkDescriptorPool ds_pool;
8355     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8356     ASSERT_VK_SUCCESS(err);
8357
8358     VkDescriptorSetLayoutBinding dsl_binding = {};
8359     dsl_binding.binding = 0;
8360     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8361     dsl_binding.descriptorCount = 1;
8362     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8363     dsl_binding.pImmutableSamplers = NULL;
8364
8365     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8366     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8367     ds_layout_ci.pNext = NULL;
8368     ds_layout_ci.bindingCount = 1;
8369     ds_layout_ci.pBindings = &dsl_binding;
8370     VkDescriptorSetLayout ds_layout;
8371     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8372     ASSERT_VK_SUCCESS(err);
8373
8374     VkDescriptorSet descriptorSet;
8375     VkDescriptorSetAllocateInfo alloc_info = {};
8376     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8377     alloc_info.descriptorSetCount = 1;
8378     alloc_info.descriptorPool = ds_pool;
8379     alloc_info.pSetLayouts = &ds_layout;
8380     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8381     ASSERT_VK_SUCCESS(err);
8382
8383     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8384     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8385     pipeline_layout_ci.pNext = NULL;
8386     pipeline_layout_ci.setLayoutCount = 1;
8387     pipeline_layout_ci.pSetLayouts = &ds_layout;
8388
8389     VkPipelineLayout pipeline_layout;
8390     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8391     ASSERT_VK_SUCCESS(err);
8392
8393     // Create a buffer to update the descriptor with
8394     uint32_t qfi = 0;
8395     VkBufferCreateInfo buffCI = {};
8396     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8397     buffCI.size = 1024;
8398     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8399     buffCI.queueFamilyIndexCount = 1;
8400     buffCI.pQueueFamilyIndices = &qfi;
8401
8402     VkBuffer dyub;
8403     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8404     ASSERT_VK_SUCCESS(err);
8405     // Allocate memory and bind to buffer so we can make it to the appropriate
8406     // error
8407     VkMemoryAllocateInfo mem_alloc = {};
8408     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8409     mem_alloc.pNext = NULL;
8410     mem_alloc.allocationSize = 1024;
8411     mem_alloc.memoryTypeIndex = 0;
8412
8413     VkMemoryRequirements memReqs;
8414     vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
8415     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
8416     if (!pass) {
8417         vkDestroyBuffer(m_device->device(), dyub, NULL);
8418         return;
8419     }
8420
8421     VkDeviceMemory mem;
8422     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
8423     ASSERT_VK_SUCCESS(err);
8424     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8425     ASSERT_VK_SUCCESS(err);
8426     // Correctly update descriptor to avoid "NOT_UPDATED" error
8427     VkDescriptorBufferInfo buffInfo = {};
8428     buffInfo.buffer = dyub;
8429     buffInfo.offset = 0;
8430     buffInfo.range = 1024;
8431
8432     VkWriteDescriptorSet descriptor_write;
8433     memset(&descriptor_write, 0, sizeof(descriptor_write));
8434     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8435     descriptor_write.dstSet = descriptorSet;
8436     descriptor_write.dstBinding = 0;
8437     descriptor_write.descriptorCount = 1;
8438     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8439     descriptor_write.pBufferInfo = &buffInfo;
8440
8441     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8442
8443     BeginCommandBuffer();
8444     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8445                             &descriptorSet, 0, NULL);
8446     m_errorMonitor->VerifyFound();
8447     uint32_t pDynOff[2] = {512, 756};
8448     // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
8449     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8450                                          "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
8451     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8452                             &descriptorSet, 2, pDynOff);
8453     m_errorMonitor->VerifyFound();
8454     // Finally cause error due to dynamicOffset being too big
8455     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with "
8456                                                                         "offset 0 and range 1024 that "
8457                                                                         "oversteps the buffer size of 1024");
8458     // Create PSO to be used for draw-time errors below
8459     char const *vsSource = "#version 450\n"
8460                            "\n"
8461                            "out gl_PerVertex { \n"
8462                            "    vec4 gl_Position;\n"
8463                            "};\n"
8464                            "void main(){\n"
8465                            "   gl_Position = vec4(1);\n"
8466                            "}\n";
8467     char const *fsSource = "#version 450\n"
8468                            "\n"
8469                            "layout(location=0) out vec4 x;\n"
8470                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8471                            "void main(){\n"
8472                            "   x = vec4(bar.y);\n"
8473                            "}\n";
8474     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8475     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8476     VkPipelineObj pipe(m_device);
8477     pipe.AddShader(&vs);
8478     pipe.AddShader(&fs);
8479     pipe.AddColorAttachment();
8480     pipe.CreateVKPipeline(pipeline_layout, renderPass());
8481
8482     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8483     // This update should succeed, but offset size of 512 will overstep buffer
8484     // /w range 1024 & size 1024
8485     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8486                             &descriptorSet, 1, pDynOff);
8487     Draw(1, 0, 0, 0);
8488     m_errorMonitor->VerifyFound();
8489
8490     vkDestroyBuffer(m_device->device(), dyub, NULL);
8491     vkFreeMemory(m_device->device(), mem, NULL);
8492
8493     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8494     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8495     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8496 }
8497
8498 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
8499     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
8500                      "that doesn't have memory bound");
8501     VkResult err;
8502     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8503                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8504     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8505                                          "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8506
8507     ASSERT_NO_FATAL_FAILURE(InitState());
8508     ASSERT_NO_FATAL_FAILURE(InitViewport());
8509     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8510
8511     VkDescriptorPoolSize ds_type_count = {};
8512     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8513     ds_type_count.descriptorCount = 1;
8514
8515     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8516     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8517     ds_pool_ci.pNext = NULL;
8518     ds_pool_ci.maxSets = 1;
8519     ds_pool_ci.poolSizeCount = 1;
8520     ds_pool_ci.pPoolSizes = &ds_type_count;
8521
8522     VkDescriptorPool ds_pool;
8523     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8524     ASSERT_VK_SUCCESS(err);
8525
8526     VkDescriptorSetLayoutBinding dsl_binding = {};
8527     dsl_binding.binding = 0;
8528     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8529     dsl_binding.descriptorCount = 1;
8530     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8531     dsl_binding.pImmutableSamplers = NULL;
8532
8533     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8534     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8535     ds_layout_ci.pNext = NULL;
8536     ds_layout_ci.bindingCount = 1;
8537     ds_layout_ci.pBindings = &dsl_binding;
8538     VkDescriptorSetLayout ds_layout;
8539     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8540     ASSERT_VK_SUCCESS(err);
8541
8542     VkDescriptorSet descriptorSet;
8543     VkDescriptorSetAllocateInfo alloc_info = {};
8544     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8545     alloc_info.descriptorSetCount = 1;
8546     alloc_info.descriptorPool = ds_pool;
8547     alloc_info.pSetLayouts = &ds_layout;
8548     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8549     ASSERT_VK_SUCCESS(err);
8550
8551     // Create a buffer to update the descriptor with
8552     uint32_t qfi = 0;
8553     VkBufferCreateInfo buffCI = {};
8554     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8555     buffCI.size = 1024;
8556     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8557     buffCI.queueFamilyIndexCount = 1;
8558     buffCI.pQueueFamilyIndices = &qfi;
8559
8560     VkBuffer dyub;
8561     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8562     ASSERT_VK_SUCCESS(err);
8563
8564     // Attempt to update descriptor without binding memory to it
8565     VkDescriptorBufferInfo buffInfo = {};
8566     buffInfo.buffer = dyub;
8567     buffInfo.offset = 0;
8568     buffInfo.range = 1024;
8569
8570     VkWriteDescriptorSet descriptor_write;
8571     memset(&descriptor_write, 0, sizeof(descriptor_write));
8572     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8573     descriptor_write.dstSet = descriptorSet;
8574     descriptor_write.dstBinding = 0;
8575     descriptor_write.descriptorCount = 1;
8576     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8577     descriptor_write.pBufferInfo = &buffInfo;
8578
8579     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8580     m_errorMonitor->VerifyFound();
8581
8582     vkDestroyBuffer(m_device->device(), dyub, NULL);
8583     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8584     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8585 }
8586
8587 TEST_F(VkLayerTest, InvalidPushConstants) {
8588     VkResult err;
8589     ASSERT_NO_FATAL_FAILURE(InitState());
8590     ASSERT_NO_FATAL_FAILURE(InitViewport());
8591     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8592
8593     VkPipelineLayout pipeline_layout;
8594     VkPushConstantRange pc_range = {};
8595     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8596     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8597     pipeline_layout_ci.pushConstantRangeCount = 1;
8598     pipeline_layout_ci.pPushConstantRanges = &pc_range;
8599
8600     //
8601     // Check for invalid push constant ranges in pipeline layouts.
8602     //
8603     struct PipelineLayoutTestCase {
8604         VkPushConstantRange const range;
8605         char const *msg;
8606     };
8607
8608     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
8609     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
8610         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
8611          "vkCreatePipelineLayout() call has push constants index 0 with "
8612          "size 0."},
8613         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8614          "vkCreatePipelineLayout() call has push constants index 0 with "
8615          "size 1."},
8616         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8617          "vkCreatePipelineLayout() call has push constants index 0 with "
8618          "size 1."},
8619         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
8620          "vkCreatePipelineLayout() call has push constants index 0 with "
8621          "size 0."},
8622         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8623          "vkCreatePipelineLayout() call has push constants index 0 with "
8624          "offset 1. Offset must"},
8625         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big},
8626          "vkCreatePipelineLayout() call has push constants index 0 "
8627          "with offset "},
8628         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
8629          "vkCreatePipelineLayout() call has push constants "
8630          "index 0 with offset "},
8631         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
8632          "vkCreatePipelineLayout() call has push constants index 0 "
8633          "with offset "},
8634         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
8635          "vkCreatePipelineLayout() call has push "
8636          "constants index 0 with offset "},
8637         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
8638          "vkCreatePipelineLayout() call has push "
8639          "constants index 0 with offset "},
8640     }};
8641
8642     // Check for invalid offset and size
8643     for (const auto &iter : range_tests) {
8644         pc_range = iter.range;
8645         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8646         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8647         m_errorMonitor->VerifyFound();
8648         if (VK_SUCCESS == err) {
8649             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8650         }
8651     }
8652
8653     // Check for invalid stage flag
8654     pc_range.offset = 0;
8655     pc_range.size = 16;
8656     pc_range.stageFlags = 0;
8657     m_errorMonitor->SetDesiredFailureMsg(
8658         VK_DEBUG_REPORT_ERROR_BIT_EXT,
8659         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
8660     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8661     m_errorMonitor->VerifyFound();
8662     if (VK_SUCCESS == err) {
8663         vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8664     }
8665
8666     // Check for overlapping ranges
8667     const uint32_t ranges_per_test = 5;
8668     struct OverlappingRangeTestCase {
8669         VkPushConstantRange const ranges[ranges_per_test];
8670         char const *msg;
8671     };
8672
8673     const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = {
8674         {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8675            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8676            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8677            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8678            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8679           "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
8680          {
8681              {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8682               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8683               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8684               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8685               {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8686              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
8687          },
8688          {
8689              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8690               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8691               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8692               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8693               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8694              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
8695          },
8696          {
8697              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8698               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8699               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8700               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8701               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8702              "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
8703          },
8704          {
8705              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8706               {VK_SHADER_STAGE_VERTEX_BIT, 32, 4},
8707               {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
8708               {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
8709               {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
8710              "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
8711          }}};
8712
8713     for (const auto &iter : overlapping_range_tests) {
8714         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8715         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
8716         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg);
8717         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8718         m_errorMonitor->VerifyFound();
8719         if (VK_SUCCESS == err) {
8720             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8721         }
8722     }
8723
8724     // Run some positive tests to make sure overlap checking in the layer is OK
8725     const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8726                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8727                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8728                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
8729                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8730                                                                                    ""},
8731                                                                                   {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
8732                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
8733                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
8734                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
8735                                                                                     {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8736                                                                                    ""}}};
8737     for (const auto &iter : overlapping_range_tests_pos) {
8738         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8739         m_errorMonitor->ExpectSuccess();
8740         err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8741         m_errorMonitor->VerifyNotFound();
8742         if (VK_SUCCESS == err) {
8743             vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8744         }
8745     }
8746
8747     //
8748     // CmdPushConstants tests
8749     //
8750     const uint8_t dummy_values[100] = {};
8751
8752     // Check for invalid offset and size and if range is within layout range(s)
8753     const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
8754         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
8755         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8756          "vkCmdPushConstants() call has push constants with size 1. Size "
8757          "must be greater than zero and a multiple of 4."},
8758         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8759          "vkCmdPushConstants() call has push constants with size 1. Size "
8760          "must be greater than zero and a multiple of 4."},
8761         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8762          "vkCmdPushConstants() call has push constants with offset 1. "
8763          "Offset must be a multiple of 4."},
8764         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8765          "vkCmdPushConstants() call has push constants with offset 1. "
8766          "Offset must be a multiple of 4."},
8767         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8768          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8769          "0x1 not within flag-matching ranges in pipeline layout"},
8770         {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8},
8771          "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = "
8772          "0x1 not within flag-matching ranges in pipeline layout"},
8773         {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8},
8774          "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = "
8775          "0x1 not within flag-matching ranges in pipeline layout"},
8776         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80},
8777          "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = "
8778          "0x1 not within flag-matching ranges in pipeline layout"},
8779         {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
8780          "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in "
8781          "any of the ranges in pipeline layout"},
8782         {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
8783          "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
8784          "any of the ranges in pipeline layout"},
8785     }};
8786
8787     BeginCommandBuffer();
8788
8789     // Setup ranges: [0,16) [64,80)
8790     const VkPushConstantRange pc_range2[] = {
8791         {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
8792     };
8793     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange);
8794     pipeline_layout_ci.pPushConstantRanges = pc_range2;
8795     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8796     ASSERT_VK_SUCCESS(err);
8797     for (const auto &iter : cmd_range_tests) {
8798         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8799         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8800                            iter.range.size, dummy_values);
8801         m_errorMonitor->VerifyFound();
8802     }
8803
8804     // Check for invalid stage flag
8805     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
8806     vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
8807     m_errorMonitor->VerifyFound();
8808     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8809
8810     // overlapping range tests with cmd
8811     const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{
8812         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8813          "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8814          "0x1 not within flag-matching ranges in pipeline layout"},
8815         {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8816          "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = "
8817          "0x1 not within flag-matching ranges in pipeline layout"},
8818         {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16},
8819          "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
8820          "0x1 not within flag-matching ranges in pipeline layout"},
8821     }};
8822     // Setup ranges:  [0,16), [20,36), [36,44), [44,52), [80,92)
8823     const VkPushConstantRange pc_range3[] = {
8824         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8825         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
8826     };
8827     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
8828     pipeline_layout_ci.pPushConstantRanges = pc_range3;
8829     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8830     ASSERT_VK_SUCCESS(err);
8831     for (const auto &iter : cmd_overlap_tests) {
8832         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8833         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8834                            iter.range.size, dummy_values);
8835         m_errorMonitor->VerifyFound();
8836     }
8837     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8838
8839     // positive overlapping range tests with cmd
8840     const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
8841         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
8842         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
8843         {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
8844         {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
8845     }};
8846     // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
8847     const VkPushConstantRange pc_range4[] = {
8848         {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8849         {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 24},
8850     };
8851     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
8852     pipeline_layout_ci.pPushConstantRanges = pc_range4;
8853     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8854     ASSERT_VK_SUCCESS(err);
8855     for (const auto &iter : cmd_overlap_tests_pos) {
8856         m_errorMonitor->ExpectSuccess();
8857         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8858                            iter.range.size, dummy_values);
8859         m_errorMonitor->VerifyNotFound();
8860     }
8861     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8862
8863     EndCommandBuffer();
8864 }
8865
8866 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
8867     // Test various desriptorSet errors with bad binding combinations
8868     VkResult err;
8869
8870     ASSERT_NO_FATAL_FAILURE(InitState());
8871     ASSERT_NO_FATAL_FAILURE(InitViewport());
8872     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8873
8874     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
8875     VkImageTiling tiling;
8876     VkFormatProperties format_properties;
8877     vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
8878     if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8879         tiling = VK_IMAGE_TILING_LINEAR;
8880     } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8881         tiling = VK_IMAGE_TILING_OPTIMAL;
8882     } else {
8883         printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
8884                "skipped.\n");
8885         return;
8886     }
8887
8888     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
8889     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
8890     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8891     ds_type_count[0].descriptorCount = 10;
8892     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8893     ds_type_count[1].descriptorCount = 2;
8894     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8895     ds_type_count[2].descriptorCount = 2;
8896     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
8897     ds_type_count[3].descriptorCount = 5;
8898     // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
8899     // type
8900     // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
8901     ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8902     ds_type_count[4].descriptorCount = 2;
8903
8904     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8905     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8906     ds_pool_ci.pNext = NULL;
8907     ds_pool_ci.maxSets = 5;
8908     ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
8909     ds_pool_ci.pPoolSizes = ds_type_count;
8910
8911     VkDescriptorPool ds_pool;
8912     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8913     ASSERT_VK_SUCCESS(err);
8914
8915     static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
8916     VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
8917     dsl_binding[0].binding = 0;
8918     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8919     dsl_binding[0].descriptorCount = 5;
8920     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
8921     dsl_binding[0].pImmutableSamplers = NULL;
8922
8923     // Create layout identical to set0 layout but w/ different stageFlags
8924     VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
8925     dsl_fs_stage_only.binding = 0;
8926     dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8927     dsl_fs_stage_only.descriptorCount = 5;
8928     dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at
8929                                                                  // bind time
8930     dsl_fs_stage_only.pImmutableSamplers = NULL;
8931     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8932     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8933     ds_layout_ci.pNext = NULL;
8934     ds_layout_ci.bindingCount = 1;
8935     ds_layout_ci.pBindings = dsl_binding;
8936     static const uint32_t NUM_LAYOUTS = 4;
8937     VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {};
8938     VkDescriptorSetLayout ds_layout_fs_only = {};
8939     // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
8940     // layout for error case
8941     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]);
8942     ASSERT_VK_SUCCESS(err);
8943     ds_layout_ci.pBindings = &dsl_fs_stage_only;
8944     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only);
8945     ASSERT_VK_SUCCESS(err);
8946     dsl_binding[0].binding = 0;
8947     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8948     dsl_binding[0].descriptorCount = 2;
8949     dsl_binding[1].binding = 1;
8950     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8951     dsl_binding[1].descriptorCount = 2;
8952     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
8953     dsl_binding[1].pImmutableSamplers = NULL;
8954     ds_layout_ci.pBindings = dsl_binding;
8955     ds_layout_ci.bindingCount = 2;
8956     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]);
8957     ASSERT_VK_SUCCESS(err);
8958     dsl_binding[0].binding = 0;
8959     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8960     dsl_binding[0].descriptorCount = 5;
8961     ds_layout_ci.bindingCount = 1;
8962     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]);
8963     ASSERT_VK_SUCCESS(err);
8964     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8965     dsl_binding[0].descriptorCount = 2;
8966     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]);
8967     ASSERT_VK_SUCCESS(err);
8968
8969     static const uint32_t NUM_SETS = 4;
8970     VkDescriptorSet descriptorSet[NUM_SETS] = {};
8971     VkDescriptorSetAllocateInfo alloc_info = {};
8972     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8973     alloc_info.descriptorSetCount = NUM_LAYOUTS;
8974     alloc_info.descriptorPool = ds_pool;
8975     alloc_info.pSetLayouts = ds_layout;
8976     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
8977     ASSERT_VK_SUCCESS(err);
8978     VkDescriptorSet ds0_fs_only = {};
8979     alloc_info.descriptorSetCount = 1;
8980     alloc_info.pSetLayouts = &ds_layout_fs_only;
8981     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
8982     ASSERT_VK_SUCCESS(err);
8983
8984     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8985     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8986     pipeline_layout_ci.pNext = NULL;
8987     pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS;
8988     pipeline_layout_ci.pSetLayouts = ds_layout;
8989
8990     VkPipelineLayout pipeline_layout;
8991     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8992     ASSERT_VK_SUCCESS(err);
8993     // Create pipelineLayout with only one setLayout
8994     pipeline_layout_ci.setLayoutCount = 1;
8995     VkPipelineLayout single_pipe_layout;
8996     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout);
8997     ASSERT_VK_SUCCESS(err);
8998     // Create pipelineLayout with 2 descriptor setLayout at index 0
8999     pipeline_layout_ci.pSetLayouts = &ds_layout[3];
9000     VkPipelineLayout pipe_layout_one_desc;
9001     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc);
9002     ASSERT_VK_SUCCESS(err);
9003     // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
9004     pipeline_layout_ci.pSetLayouts = &ds_layout[2];
9005     VkPipelineLayout pipe_layout_five_samp;
9006     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp);
9007     ASSERT_VK_SUCCESS(err);
9008     // Create pipelineLayout with UB type, but stageFlags for FS only
9009     pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only;
9010     VkPipelineLayout pipe_layout_fs_only;
9011     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only);
9012     ASSERT_VK_SUCCESS(err);
9013     // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
9014     VkDescriptorSetLayout pl_bad_s0[2] = {};
9015     pl_bad_s0[0] = ds_layout_fs_only;
9016     pl_bad_s0[1] = ds_layout[1];
9017     pipeline_layout_ci.setLayoutCount = 2;
9018     pipeline_layout_ci.pSetLayouts = pl_bad_s0;
9019     VkPipelineLayout pipe_layout_bad_set0;
9020     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0);
9021     ASSERT_VK_SUCCESS(err);
9022
9023     // Create a buffer to update the descriptor with
9024     uint32_t qfi = 0;
9025     VkBufferCreateInfo buffCI = {};
9026     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9027     buffCI.size = 1024;
9028     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
9029     buffCI.queueFamilyIndexCount = 1;
9030     buffCI.pQueueFamilyIndices = &qfi;
9031
9032     VkBuffer dyub;
9033     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
9034     ASSERT_VK_SUCCESS(err);
9035     // Correctly update descriptor to avoid "NOT_UPDATED" error
9036     static const uint32_t NUM_BUFFS = 5;
9037     VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {};
9038     for (uint32_t i = 0; i < NUM_BUFFS; ++i) {
9039         buffInfo[i].buffer = dyub;
9040         buffInfo[i].offset = 0;
9041         buffInfo[i].range = 1024;
9042     }
9043     VkImage image;
9044     const int32_t tex_width = 32;
9045     const int32_t tex_height = 32;
9046     VkImageCreateInfo image_create_info = {};
9047     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9048     image_create_info.pNext = NULL;
9049     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9050     image_create_info.format = tex_format;
9051     image_create_info.extent.width = tex_width;
9052     image_create_info.extent.height = tex_height;
9053     image_create_info.extent.depth = 1;
9054     image_create_info.mipLevels = 1;
9055     image_create_info.arrayLayers = 1;
9056     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9057     image_create_info.tiling = tiling;
9058     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
9059     image_create_info.flags = 0;
9060     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9061     ASSERT_VK_SUCCESS(err);
9062
9063     VkMemoryRequirements memReqs;
9064     VkDeviceMemory imageMem;
9065     bool pass;
9066     VkMemoryAllocateInfo memAlloc = {};
9067     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9068     memAlloc.pNext = NULL;
9069     memAlloc.allocationSize = 0;
9070     memAlloc.memoryTypeIndex = 0;
9071     vkGetImageMemoryRequirements(m_device->device(), image, &memReqs);
9072     memAlloc.allocationSize = memReqs.size;
9073     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
9074     ASSERT_TRUE(pass);
9075     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem);
9076     ASSERT_VK_SUCCESS(err);
9077     err = vkBindImageMemory(m_device->device(), image, imageMem, 0);
9078     ASSERT_VK_SUCCESS(err);
9079
9080     VkImageViewCreateInfo image_view_create_info = {};
9081     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
9082     image_view_create_info.image = image;
9083     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
9084     image_view_create_info.format = tex_format;
9085     image_view_create_info.subresourceRange.layerCount = 1;
9086     image_view_create_info.subresourceRange.baseMipLevel = 0;
9087     image_view_create_info.subresourceRange.levelCount = 1;
9088     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9089
9090     VkImageView view;
9091     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
9092     ASSERT_VK_SUCCESS(err);
9093     VkDescriptorImageInfo imageInfo[4] = {};
9094     imageInfo[0].imageView = view;
9095     imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9096     imageInfo[1].imageView = view;
9097     imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9098     imageInfo[2].imageView = view;
9099     imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9100     imageInfo[3].imageView = view;
9101     imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9102
9103     static const uint32_t NUM_SET_UPDATES = 3;
9104     VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
9105     descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9106     descriptor_write[0].dstSet = descriptorSet[0];
9107     descriptor_write[0].dstBinding = 0;
9108     descriptor_write[0].descriptorCount = 5;
9109     descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9110     descriptor_write[0].pBufferInfo = buffInfo;
9111     descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9112     descriptor_write[1].dstSet = descriptorSet[1];
9113     descriptor_write[1].dstBinding = 0;
9114     descriptor_write[1].descriptorCount = 2;
9115     descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9116     descriptor_write[1].pImageInfo = imageInfo;
9117     descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9118     descriptor_write[2].dstSet = descriptorSet[1];
9119     descriptor_write[2].dstBinding = 1;
9120     descriptor_write[2].descriptorCount = 2;
9121     descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9122     descriptor_write[2].pImageInfo = &imageInfo[2];
9123
9124     vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL);
9125
9126     // Create PSO to be used for draw-time errors below
9127     char const *vsSource = "#version 450\n"
9128                            "\n"
9129                            "out gl_PerVertex {\n"
9130                            "    vec4 gl_Position;\n"
9131                            "};\n"
9132                            "void main(){\n"
9133                            "   gl_Position = vec4(1);\n"
9134                            "}\n";
9135     char const *fsSource = "#version 450\n"
9136                            "\n"
9137                            "layout(location=0) out vec4 x;\n"
9138                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
9139                            "void main(){\n"
9140                            "   x = vec4(bar.y);\n"
9141                            "}\n";
9142     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9143     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9144     VkPipelineObj pipe(m_device);
9145     pipe.AddShader(&vs);
9146     pipe.AddShader(&fs);
9147     pipe.AddColorAttachment();
9148     pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass());
9149
9150     BeginCommandBuffer();
9151
9152     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9153     // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
9154     // of PSO
9155     //  here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
9156     //  cmd_pipeline.c
9157     //  due to the fact that cmd_alloc_dset_data() has not been called in
9158     //  cmd_bind_graphics_pipeline()
9159     // TODO : Want to cause various binding incompatibility issues here to test
9160     // DrawState
9161     //  First cause various verify_layout_compatibility() fails
9162     //  Second disturb early and late sets and verify INFO msgs
9163     // verify_set_layout_compatibility fail cases:
9164     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
9165     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object ");
9166     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
9167                             (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL);
9168     m_errorMonitor->VerifyFound();
9169
9170     // 2. layoutIndex exceeds # of layouts in layout
9171     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
9172     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2,
9173                             &descriptorSet[0], 0, NULL);
9174     m_errorMonitor->VerifyFound();
9175
9176     vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL);
9177     // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
9178     // descriptors
9179     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
9180     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1,
9181                             &descriptorSet[0], 0, NULL);
9182     m_errorMonitor->VerifyFound();
9183
9184     vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL);
9185     // 4. same # of descriptors but mismatch in type
9186     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
9187     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1,
9188                             &descriptorSet[0], 0, NULL);
9189     m_errorMonitor->VerifyFound();
9190
9191     vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL);
9192     // 5. same # of descriptors but mismatch in stageFlags
9193     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9194                                          " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
9195     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9196                             &descriptorSet[0], 0, NULL);
9197     m_errorMonitor->VerifyFound();
9198
9199     // Cause INFO messages due to disturbing previously bound Sets
9200     // First bind sets 0 & 1
9201     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9202                             &descriptorSet[0], 0, NULL);
9203     // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout
9204     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed ");
9205     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9206                             &descriptorSet[1], 0, NULL);
9207     m_errorMonitor->VerifyFound();
9208
9209     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9210                             &descriptorSet[0], 0, NULL);
9211     // 2. Disturb set after last bound set
9212     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and "
9213                                                                                       "any subsequent sets were disturbed ");
9214     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9215                             &ds0_fs_only, 0, NULL);
9216     m_errorMonitor->VerifyFound();
9217
9218     // Now that we're done actively using the pipelineLayout that gfx pipeline
9219     //  was created with, we should be able to delete it. Do that now to verify
9220     //  that validation obeys pipelineLayout lifetime
9221     vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
9222
9223     // Cause draw-time errors due to PSO incompatibilities
9224     // 1. Error due to not binding required set (we actually use same code as
9225     // above to disturb set0)
9226     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9227                             &descriptorSet[0], 0, NULL);
9228     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9229                             &descriptorSet[1], 0, NULL);
9230     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
9231     Draw(1, 0, 0, 0);
9232     m_errorMonitor->VerifyFound();
9233
9234     vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL);
9235     // 2. Error due to bound set not being compatible with PSO's
9236     // VkPipelineLayout (diff stageFlags in this case)
9237     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9238                             &descriptorSet[0], 0, NULL);
9239     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
9240     Draw(1, 0, 0, 0);
9241     m_errorMonitor->VerifyFound();
9242
9243     // Remaining clean-up
9244     for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
9245         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
9246     }
9247     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
9248     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
9249     vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
9250     vkDestroyBuffer(m_device->device(), dyub, NULL);
9251     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9252     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9253     vkFreeMemory(m_device->device(), imageMem, NULL);
9254     vkDestroyImage(m_device->device(), image, NULL);
9255     vkDestroyImageView(m_device->device(), view, NULL);
9256 }
9257
9258 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
9259
9260     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9261                                          "You must call vkBeginCommandBuffer() before this call to ");
9262
9263     ASSERT_NO_FATAL_FAILURE(InitState());
9264     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9265     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
9266     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9267
9268     m_errorMonitor->VerifyFound();
9269 }
9270
9271 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
9272     VkResult err;
9273     VkCommandBuffer draw_cmd;
9274
9275     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter.");
9276
9277     ASSERT_NO_FATAL_FAILURE(InitState());
9278
9279     VkCommandBufferAllocateInfo cmd = {};
9280     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
9281     cmd.pNext = NULL;
9282     cmd.commandPool = m_commandPool;
9283     cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
9284     cmd.commandBufferCount = 1;
9285
9286     err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd);
9287     ASSERT_VK_SUCCESS(err);
9288
9289     // Force the failure by not setting the Renderpass and Framebuffer fields
9290     VkCommandBufferBeginInfo cmd_buf_info = {};
9291     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9292     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9293     cmd_buf_info.pNext = NULL;
9294     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
9295     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9296
9297     // The error should be caught by validation of the BeginCommandBuffer call
9298     vkBeginCommandBuffer(draw_cmd, &cmd_buf_info);
9299
9300     m_errorMonitor->VerifyFound();
9301     vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd);
9302 }
9303
9304 TEST_F(VkLayerTest, CommandBufferResetErrors) {
9305     // Cause error due to Begin while recording CB
9306     // Then cause 2 errors for attempting to reset CB w/o having
9307     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
9308     // which CBs were allocated. Note that this bit is off by default.
9309     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
9310
9311     ASSERT_NO_FATAL_FAILURE(InitState());
9312
9313     // Calls AllocateCommandBuffers
9314     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9315
9316     // Force the failure by setting the Renderpass and Framebuffer fields with
9317     // (fake) data
9318     VkCommandBufferBeginInfo cmd_buf_info = {};
9319     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9320     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9321     cmd_buf_info.pNext = NULL;
9322     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
9323     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9324
9325     // Begin CB to transition to recording state
9326     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9327     // Can't re-begin. This should trigger error
9328     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9329     m_errorMonitor->VerifyFound();
9330
9331     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer ");
9332     VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
9333     // Reset attempt will trigger error due to incorrect CommandPool state
9334     vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags);
9335     m_errorMonitor->VerifyFound();
9336
9337     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from ");
9338     // Transition CB to RECORDED state
9339     vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9340     // Now attempting to Begin will implicitly reset, which triggers error
9341     vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9342     m_errorMonitor->VerifyFound();
9343 }
9344
9345 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
9346     // Attempt to Create Gfx Pipeline w/o a VS
9347     VkResult err;
9348
9349     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
9350
9351     ASSERT_NO_FATAL_FAILURE(InitState());
9352     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9353
9354     VkDescriptorPoolSize ds_type_count = {};
9355     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9356     ds_type_count.descriptorCount = 1;
9357
9358     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9359     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9360     ds_pool_ci.pNext = NULL;
9361     ds_pool_ci.maxSets = 1;
9362     ds_pool_ci.poolSizeCount = 1;
9363     ds_pool_ci.pPoolSizes = &ds_type_count;
9364
9365     VkDescriptorPool ds_pool;
9366     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9367     ASSERT_VK_SUCCESS(err);
9368
9369     VkDescriptorSetLayoutBinding dsl_binding = {};
9370     dsl_binding.binding = 0;
9371     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9372     dsl_binding.descriptorCount = 1;
9373     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9374     dsl_binding.pImmutableSamplers = NULL;
9375
9376     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9377     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9378     ds_layout_ci.pNext = NULL;
9379     ds_layout_ci.bindingCount = 1;
9380     ds_layout_ci.pBindings = &dsl_binding;
9381
9382     VkDescriptorSetLayout ds_layout;
9383     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9384     ASSERT_VK_SUCCESS(err);
9385
9386     VkDescriptorSet descriptorSet;
9387     VkDescriptorSetAllocateInfo alloc_info = {};
9388     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9389     alloc_info.descriptorSetCount = 1;
9390     alloc_info.descriptorPool = ds_pool;
9391     alloc_info.pSetLayouts = &ds_layout;
9392     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9393     ASSERT_VK_SUCCESS(err);
9394
9395     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9396     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9397     pipeline_layout_ci.setLayoutCount = 1;
9398     pipeline_layout_ci.pSetLayouts = &ds_layout;
9399
9400     VkPipelineLayout pipeline_layout;
9401     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9402     ASSERT_VK_SUCCESS(err);
9403
9404     VkViewport vp = {}; // Just need dummy vp to point to
9405     VkRect2D sc = {};   // dummy scissor to point to
9406
9407     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9408     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9409     vp_state_ci.scissorCount = 1;
9410     vp_state_ci.pScissors = &sc;
9411     vp_state_ci.viewportCount = 1;
9412     vp_state_ci.pViewports = &vp;
9413
9414     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9415     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9416     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9417     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9418     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9419     rs_state_ci.depthClampEnable = VK_FALSE;
9420     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9421     rs_state_ci.depthBiasEnable = VK_FALSE;
9422
9423     VkGraphicsPipelineCreateInfo gp_ci = {};
9424     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9425     gp_ci.pViewportState = &vp_state_ci;
9426     gp_ci.pRasterizationState = &rs_state_ci;
9427     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9428     gp_ci.layout = pipeline_layout;
9429     gp_ci.renderPass = renderPass();
9430
9431     VkPipelineCacheCreateInfo pc_ci = {};
9432     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9433     pc_ci.initialDataSize = 0;
9434     pc_ci.pInitialData = 0;
9435
9436     VkPipeline pipeline;
9437     VkPipelineCache pipelineCache;
9438
9439     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9440     ASSERT_VK_SUCCESS(err);
9441     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9442
9443     m_errorMonitor->VerifyFound();
9444
9445     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9446     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9447     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9448     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9449 }
9450 /*// TODO : This test should be good, but needs Tess support in compiler to run
9451 TEST_F(VkLayerTest, InvalidPatchControlPoints)
9452 {
9453     // Attempt to Create Gfx Pipeline w/o a VS
9454     VkResult        err;
9455
9456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9457         "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
9458 primitive ");
9459
9460     ASSERT_NO_FATAL_FAILURE(InitState());
9461     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9462
9463     VkDescriptorPoolSize ds_type_count = {};
9464         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9465         ds_type_count.descriptorCount = 1;
9466
9467     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9468         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9469         ds_pool_ci.pNext = NULL;
9470         ds_pool_ci.poolSizeCount = 1;
9471         ds_pool_ci.pPoolSizes = &ds_type_count;
9472
9473     VkDescriptorPool ds_pool;
9474     err = vkCreateDescriptorPool(m_device->device(),
9475 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
9476     ASSERT_VK_SUCCESS(err);
9477
9478     VkDescriptorSetLayoutBinding dsl_binding = {};
9479         dsl_binding.binding = 0;
9480         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9481         dsl_binding.descriptorCount = 1;
9482         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9483         dsl_binding.pImmutableSamplers = NULL;
9484
9485     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9486         ds_layout_ci.sType =
9487 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9488         ds_layout_ci.pNext = NULL;
9489         ds_layout_ci.bindingCount = 1;
9490         ds_layout_ci.pBindings = &dsl_binding;
9491
9492     VkDescriptorSetLayout ds_layout;
9493     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
9494 &ds_layout);
9495     ASSERT_VK_SUCCESS(err);
9496
9497     VkDescriptorSet descriptorSet;
9498     err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
9499 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
9500     ASSERT_VK_SUCCESS(err);
9501
9502     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9503         pipeline_layout_ci.sType =
9504 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9505         pipeline_layout_ci.pNext = NULL;
9506         pipeline_layout_ci.setLayoutCount = 1;
9507         pipeline_layout_ci.pSetLayouts = &ds_layout;
9508
9509     VkPipelineLayout pipeline_layout;
9510     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
9511 &pipeline_layout);
9512     ASSERT_VK_SUCCESS(err);
9513
9514     VkPipelineShaderStageCreateInfo shaderStages[3];
9515     memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
9516
9517     VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
9518 this);
9519     // Just using VS txt for Tess shaders as we don't care about functionality
9520     VkShaderObj
9521 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9522 this);
9523     VkShaderObj
9524 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9525 this);
9526
9527     shaderStages[0].sType  =
9528 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9529     shaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
9530     shaderStages[0].shader = vs.handle();
9531     shaderStages[1].sType  =
9532 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9533     shaderStages[1].stage  = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
9534     shaderStages[1].shader = tc.handle();
9535     shaderStages[2].sType  =
9536 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9537     shaderStages[2].stage  = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
9538     shaderStages[2].shader = te.handle();
9539
9540     VkPipelineInputAssemblyStateCreateInfo iaCI = {};
9541         iaCI.sType =
9542 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9543         iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
9544
9545     VkPipelineTessellationStateCreateInfo tsCI = {};
9546         tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
9547         tsCI.patchControlPoints = 0; // This will cause an error
9548
9549     VkGraphicsPipelineCreateInfo gp_ci = {};
9550         gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9551         gp_ci.pNext = NULL;
9552         gp_ci.stageCount = 3;
9553         gp_ci.pStages = shaderStages;
9554         gp_ci.pVertexInputState = NULL;
9555         gp_ci.pInputAssemblyState = &iaCI;
9556         gp_ci.pTessellationState = &tsCI;
9557         gp_ci.pViewportState = NULL;
9558         gp_ci.pRasterizationState = NULL;
9559         gp_ci.pMultisampleState = NULL;
9560         gp_ci.pDepthStencilState = NULL;
9561         gp_ci.pColorBlendState = NULL;
9562         gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9563         gp_ci.layout = pipeline_layout;
9564         gp_ci.renderPass = renderPass();
9565
9566     VkPipelineCacheCreateInfo pc_ci = {};
9567         pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9568         pc_ci.pNext = NULL;
9569         pc_ci.initialSize = 0;
9570         pc_ci.initialData = 0;
9571         pc_ci.maxSize = 0;
9572
9573     VkPipeline pipeline;
9574     VkPipelineCache pipelineCache;
9575
9576     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
9577 &pipelineCache);
9578     ASSERT_VK_SUCCESS(err);
9579     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
9580 &gp_ci, NULL, &pipeline);
9581
9582     m_errorMonitor->VerifyFound();
9583
9584     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9585     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9586     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9587     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9588 }
9589 */
9590 // Set scissor and viewport counts to different numbers
9591 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) {
9592     VkResult err;
9593
9594     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9595                                          "Gfx Pipeline viewport count (1) must match scissor count (0).");
9596
9597     ASSERT_NO_FATAL_FAILURE(InitState());
9598     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9599
9600     VkDescriptorPoolSize ds_type_count = {};
9601     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9602     ds_type_count.descriptorCount = 1;
9603
9604     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9605     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9606     ds_pool_ci.maxSets = 1;
9607     ds_pool_ci.poolSizeCount = 1;
9608     ds_pool_ci.pPoolSizes = &ds_type_count;
9609
9610     VkDescriptorPool ds_pool;
9611     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9612     ASSERT_VK_SUCCESS(err);
9613
9614     VkDescriptorSetLayoutBinding dsl_binding = {};
9615     dsl_binding.binding = 0;
9616     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9617     dsl_binding.descriptorCount = 1;
9618     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9619
9620     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9621     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9622     ds_layout_ci.bindingCount = 1;
9623     ds_layout_ci.pBindings = &dsl_binding;
9624
9625     VkDescriptorSetLayout ds_layout;
9626     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9627     ASSERT_VK_SUCCESS(err);
9628
9629     VkDescriptorSet descriptorSet;
9630     VkDescriptorSetAllocateInfo alloc_info = {};
9631     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9632     alloc_info.descriptorSetCount = 1;
9633     alloc_info.descriptorPool = ds_pool;
9634     alloc_info.pSetLayouts = &ds_layout;
9635     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9636     ASSERT_VK_SUCCESS(err);
9637
9638     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9639     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9640     pipeline_layout_ci.setLayoutCount = 1;
9641     pipeline_layout_ci.pSetLayouts = &ds_layout;
9642
9643     VkPipelineLayout pipeline_layout;
9644     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9645     ASSERT_VK_SUCCESS(err);
9646
9647     VkViewport vp = {}; // Just need dummy vp to point to
9648
9649     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9650     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9651     vp_state_ci.scissorCount = 0;
9652     vp_state_ci.viewportCount = 1; // Count mismatch should cause error
9653     vp_state_ci.pViewports = &vp;
9654
9655     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9656     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9657     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9658     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9659     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9660     rs_state_ci.depthClampEnable = VK_FALSE;
9661     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9662     rs_state_ci.depthBiasEnable = VK_FALSE;
9663
9664     VkPipelineShaderStageCreateInfo shaderStages[2];
9665     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9666
9667     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9668     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9669     // but add it to be able to run on more devices
9670     shaderStages[0] = vs.GetStageCreateInfo();
9671     shaderStages[1] = fs.GetStageCreateInfo();
9672
9673     VkGraphicsPipelineCreateInfo gp_ci = {};
9674     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9675     gp_ci.stageCount = 2;
9676     gp_ci.pStages = shaderStages;
9677     gp_ci.pViewportState = &vp_state_ci;
9678     gp_ci.pRasterizationState = &rs_state_ci;
9679     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9680     gp_ci.layout = pipeline_layout;
9681     gp_ci.renderPass = renderPass();
9682
9683     VkPipelineCacheCreateInfo pc_ci = {};
9684     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9685
9686     VkPipeline pipeline;
9687     VkPipelineCache pipelineCache;
9688
9689     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9690     ASSERT_VK_SUCCESS(err);
9691     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9692
9693     m_errorMonitor->VerifyFound();
9694
9695     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9696     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9697     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9698     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9699 }
9700 // Don't set viewport state in PSO. This is an error b/c we always need this
9701 // state
9702 //  for the counts even if the data is going to be set dynamically.
9703 TEST_F(VkLayerTest, PSOViewportStateNotSet) {
9704     // Attempt to Create Gfx Pipeline w/o a VS
9705     VkResult err;
9706
9707     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if ");
9708
9709     ASSERT_NO_FATAL_FAILURE(InitState());
9710     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9711
9712     VkDescriptorPoolSize ds_type_count = {};
9713     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9714     ds_type_count.descriptorCount = 1;
9715
9716     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9717     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9718     ds_pool_ci.maxSets = 1;
9719     ds_pool_ci.poolSizeCount = 1;
9720     ds_pool_ci.pPoolSizes = &ds_type_count;
9721
9722     VkDescriptorPool ds_pool;
9723     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9724     ASSERT_VK_SUCCESS(err);
9725
9726     VkDescriptorSetLayoutBinding dsl_binding = {};
9727     dsl_binding.binding = 0;
9728     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9729     dsl_binding.descriptorCount = 1;
9730     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9731
9732     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9733     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9734     ds_layout_ci.bindingCount = 1;
9735     ds_layout_ci.pBindings = &dsl_binding;
9736
9737     VkDescriptorSetLayout ds_layout;
9738     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9739     ASSERT_VK_SUCCESS(err);
9740
9741     VkDescriptorSet descriptorSet;
9742     VkDescriptorSetAllocateInfo alloc_info = {};
9743     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9744     alloc_info.descriptorSetCount = 1;
9745     alloc_info.descriptorPool = ds_pool;
9746     alloc_info.pSetLayouts = &ds_layout;
9747     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9748     ASSERT_VK_SUCCESS(err);
9749
9750     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9751     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9752     pipeline_layout_ci.setLayoutCount = 1;
9753     pipeline_layout_ci.pSetLayouts = &ds_layout;
9754
9755     VkPipelineLayout pipeline_layout;
9756     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9757     ASSERT_VK_SUCCESS(err);
9758
9759     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9760     // Set scissor as dynamic to avoid second error
9761     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9762     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9763     dyn_state_ci.dynamicStateCount = 1;
9764     dyn_state_ci.pDynamicStates = &sc_state;
9765
9766     VkPipelineShaderStageCreateInfo shaderStages[2];
9767     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9768
9769     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9770     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9771     // but add it to be able to run on more devices
9772     shaderStages[0] = vs.GetStageCreateInfo();
9773     shaderStages[1] = fs.GetStageCreateInfo();
9774
9775     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9776     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9777     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9778     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9779     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9780     rs_state_ci.depthClampEnable = VK_FALSE;
9781     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9782     rs_state_ci.depthBiasEnable = VK_FALSE;
9783
9784     VkGraphicsPipelineCreateInfo gp_ci = {};
9785     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9786     gp_ci.stageCount = 2;
9787     gp_ci.pStages = shaderStages;
9788     gp_ci.pRasterizationState = &rs_state_ci;
9789     gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state
9790                                  // should cause validation error
9791     gp_ci.pDynamicState = &dyn_state_ci;
9792     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9793     gp_ci.layout = pipeline_layout;
9794     gp_ci.renderPass = renderPass();
9795
9796     VkPipelineCacheCreateInfo pc_ci = {};
9797     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9798
9799     VkPipeline pipeline;
9800     VkPipelineCache pipelineCache;
9801
9802     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9803     ASSERT_VK_SUCCESS(err);
9804     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9805
9806     m_errorMonitor->VerifyFound();
9807
9808     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9809     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9810     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9811     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9812 }
9813 // Create PSO w/o non-zero viewportCount but no viewport data
9814 // Then run second test where dynamic scissor count doesn't match PSO scissor
9815 // count
9816 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) {
9817     VkResult err;
9818
9819     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9820                                          "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
9821
9822     ASSERT_NO_FATAL_FAILURE(InitState());
9823
9824     if (!m_device->phy().features().multiViewport) {
9825         printf("Device does not support multiple viewports/scissors; skipped.\n");
9826         return;
9827     }
9828
9829     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9830
9831     VkDescriptorPoolSize ds_type_count = {};
9832     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9833     ds_type_count.descriptorCount = 1;
9834
9835     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9836     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9837     ds_pool_ci.maxSets = 1;
9838     ds_pool_ci.poolSizeCount = 1;
9839     ds_pool_ci.pPoolSizes = &ds_type_count;
9840
9841     VkDescriptorPool ds_pool;
9842     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9843     ASSERT_VK_SUCCESS(err);
9844
9845     VkDescriptorSetLayoutBinding dsl_binding = {};
9846     dsl_binding.binding = 0;
9847     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9848     dsl_binding.descriptorCount = 1;
9849     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9850
9851     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9852     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9853     ds_layout_ci.bindingCount = 1;
9854     ds_layout_ci.pBindings = &dsl_binding;
9855
9856     VkDescriptorSetLayout ds_layout;
9857     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9858     ASSERT_VK_SUCCESS(err);
9859
9860     VkDescriptorSet descriptorSet;
9861     VkDescriptorSetAllocateInfo alloc_info = {};
9862     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9863     alloc_info.descriptorSetCount = 1;
9864     alloc_info.descriptorPool = ds_pool;
9865     alloc_info.pSetLayouts = &ds_layout;
9866     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9867     ASSERT_VK_SUCCESS(err);
9868
9869     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9870     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9871     pipeline_layout_ci.setLayoutCount = 1;
9872     pipeline_layout_ci.pSetLayouts = &ds_layout;
9873
9874     VkPipelineLayout pipeline_layout;
9875     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9876     ASSERT_VK_SUCCESS(err);
9877
9878     VkPipelineViewportStateCreateInfo vp_state_ci = {};
9879     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9880     vp_state_ci.viewportCount = 1;
9881     vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error
9882     vp_state_ci.scissorCount = 1;
9883     vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error
9884
9885     VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9886     // Set scissor as dynamic to avoid that error
9887     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9888     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9889     dyn_state_ci.dynamicStateCount = 1;
9890     dyn_state_ci.pDynamicStates = &sc_state;
9891
9892     VkPipelineShaderStageCreateInfo shaderStages[2];
9893     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9894
9895     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9896     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9897     // but add it to be able to run on more devices
9898     shaderStages[0] = vs.GetStageCreateInfo();
9899     shaderStages[1] = fs.GetStageCreateInfo();
9900
9901     VkPipelineVertexInputStateCreateInfo vi_ci = {};
9902     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
9903     vi_ci.pNext = nullptr;
9904     vi_ci.vertexBindingDescriptionCount = 0;
9905     vi_ci.pVertexBindingDescriptions = nullptr;
9906     vi_ci.vertexAttributeDescriptionCount = 0;
9907     vi_ci.pVertexAttributeDescriptions = nullptr;
9908
9909     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
9910     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9911     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9912
9913     VkPipelineRasterizationStateCreateInfo rs_ci = {};
9914     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9915     rs_ci.pNext = nullptr;
9916
9917     VkPipelineColorBlendAttachmentState att = {};
9918     att.blendEnable = VK_FALSE;
9919     att.colorWriteMask = 0xf;
9920
9921     VkPipelineColorBlendStateCreateInfo cb_ci = {};
9922     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
9923     cb_ci.pNext = nullptr;
9924     cb_ci.attachmentCount = 1;
9925     cb_ci.pAttachments = &att;
9926
9927     VkGraphicsPipelineCreateInfo gp_ci = {};
9928     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9929     gp_ci.stageCount = 2;
9930     gp_ci.pStages = shaderStages;
9931     gp_ci.pVertexInputState = &vi_ci;
9932     gp_ci.pInputAssemblyState = &ia_ci;
9933     gp_ci.pViewportState = &vp_state_ci;
9934     gp_ci.pRasterizationState = &rs_ci;
9935     gp_ci.pColorBlendState = &cb_ci;
9936     gp_ci.pDynamicState = &dyn_state_ci;
9937     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9938     gp_ci.layout = pipeline_layout;
9939     gp_ci.renderPass = renderPass();
9940
9941     VkPipelineCacheCreateInfo pc_ci = {};
9942     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9943
9944     VkPipeline pipeline;
9945     VkPipelineCache pipelineCache;
9946
9947     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9948     ASSERT_VK_SUCCESS(err);
9949     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9950
9951     m_errorMonitor->VerifyFound();
9952
9953     // Now hit second fail case where we set scissor w/ different count than PSO
9954     // First need to successfully create the PSO from above by setting
9955     // pViewports
9956     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
9957
9958     VkViewport vp = {}; // Just need dummy vp to point to
9959     vp_state_ci.pViewports = &vp;
9960     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9961     ASSERT_VK_SUCCESS(err);
9962     BeginCommandBuffer();
9963     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
9964     VkRect2D scissors[1] = {}; // don't care about data
9965     // Count of 2 doesn't match PSO count of 1
9966     vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
9967     Draw(1, 0, 0, 0);
9968
9969     m_errorMonitor->VerifyFound();
9970
9971     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9972     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9973     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9974     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9975     vkDestroyPipeline(m_device->device(), pipeline, NULL);
9976 }
9977 // Create PSO w/o non-zero scissorCount but no scissor data
9978 // Then run second test where dynamic viewportCount doesn't match PSO
9979 // viewportCount
9980 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) {
9981     VkResult err;
9982
9983     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
9984
9985     ASSERT_NO_FATAL_FAILURE(InitState());
9986
9987     if (!m_device->phy().features().multiViewport) {
9988         printf("Device does not support multiple viewports/scissors; skipped.\n");
9989         return;
9990     }
9991
9992     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9993
9994     VkDescriptorPoolSize ds_type_count = {};
9995     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9996     ds_type_count.descriptorCount = 1;
9997
9998     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9999     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10000     ds_pool_ci.maxSets = 1;
10001     ds_pool_ci.poolSizeCount = 1;
10002     ds_pool_ci.pPoolSizes = &ds_type_count;
10003
10004     VkDescriptorPool ds_pool;
10005     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10006     ASSERT_VK_SUCCESS(err);
10007
10008     VkDescriptorSetLayoutBinding dsl_binding = {};
10009     dsl_binding.binding = 0;
10010     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10011     dsl_binding.descriptorCount = 1;
10012     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10013
10014     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10015     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10016     ds_layout_ci.bindingCount = 1;
10017     ds_layout_ci.pBindings = &dsl_binding;
10018
10019     VkDescriptorSetLayout ds_layout;
10020     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10021     ASSERT_VK_SUCCESS(err);
10022
10023     VkDescriptorSet descriptorSet;
10024     VkDescriptorSetAllocateInfo alloc_info = {};
10025     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10026     alloc_info.descriptorSetCount = 1;
10027     alloc_info.descriptorPool = ds_pool;
10028     alloc_info.pSetLayouts = &ds_layout;
10029     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10030     ASSERT_VK_SUCCESS(err);
10031
10032     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10033     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10034     pipeline_layout_ci.setLayoutCount = 1;
10035     pipeline_layout_ci.pSetLayouts = &ds_layout;
10036
10037     VkPipelineLayout pipeline_layout;
10038     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10039     ASSERT_VK_SUCCESS(err);
10040
10041     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10042     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10043     vp_state_ci.scissorCount = 1;
10044     vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error
10045     vp_state_ci.viewportCount = 1;
10046     vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error
10047
10048     VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT;
10049     // Set scissor as dynamic to avoid that error
10050     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10051     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10052     dyn_state_ci.dynamicStateCount = 1;
10053     dyn_state_ci.pDynamicStates = &vp_state;
10054
10055     VkPipelineShaderStageCreateInfo shaderStages[2];
10056     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10057
10058     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10059     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
10060     // but add it to be able to run on more devices
10061     shaderStages[0] = vs.GetStageCreateInfo();
10062     shaderStages[1] = fs.GetStageCreateInfo();
10063
10064     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10065     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10066     vi_ci.pNext = nullptr;
10067     vi_ci.vertexBindingDescriptionCount = 0;
10068     vi_ci.pVertexBindingDescriptions = nullptr;
10069     vi_ci.vertexAttributeDescriptionCount = 0;
10070     vi_ci.pVertexAttributeDescriptions = nullptr;
10071
10072     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10073     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10074     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10075
10076     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10077     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10078     rs_ci.pNext = nullptr;
10079
10080     VkPipelineColorBlendAttachmentState att = {};
10081     att.blendEnable = VK_FALSE;
10082     att.colorWriteMask = 0xf;
10083
10084     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10085     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10086     cb_ci.pNext = nullptr;
10087     cb_ci.attachmentCount = 1;
10088     cb_ci.pAttachments = &att;
10089
10090     VkGraphicsPipelineCreateInfo gp_ci = {};
10091     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10092     gp_ci.stageCount = 2;
10093     gp_ci.pStages = shaderStages;
10094     gp_ci.pVertexInputState = &vi_ci;
10095     gp_ci.pInputAssemblyState = &ia_ci;
10096     gp_ci.pViewportState = &vp_state_ci;
10097     gp_ci.pRasterizationState = &rs_ci;
10098     gp_ci.pColorBlendState = &cb_ci;
10099     gp_ci.pDynamicState = &dyn_state_ci;
10100     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10101     gp_ci.layout = pipeline_layout;
10102     gp_ci.renderPass = renderPass();
10103
10104     VkPipelineCacheCreateInfo pc_ci = {};
10105     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10106
10107     VkPipeline pipeline;
10108     VkPipelineCache pipelineCache;
10109
10110     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10111     ASSERT_VK_SUCCESS(err);
10112     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10113
10114     m_errorMonitor->VerifyFound();
10115
10116     // Now hit second fail case where we set scissor w/ different count than PSO
10117     // First need to successfully create the PSO from above by setting
10118     // pViewports
10119     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
10120
10121     VkRect2D sc = {}; // Just need dummy vp to point to
10122     vp_state_ci.pScissors = &sc;
10123     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10124     ASSERT_VK_SUCCESS(err);
10125     BeginCommandBuffer();
10126     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10127     VkViewport viewports[1] = {}; // don't care about data
10128     // Count of 2 doesn't match PSO count of 1
10129     vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
10130     Draw(1, 0, 0, 0);
10131
10132     m_errorMonitor->VerifyFound();
10133
10134     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10135     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10136     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10137     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10138     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10139 }
10140
10141 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
10142     VkResult err;
10143
10144     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10145
10146     ASSERT_NO_FATAL_FAILURE(InitState());
10147     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10148
10149     VkDescriptorPoolSize ds_type_count = {};
10150     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10151     ds_type_count.descriptorCount = 1;
10152
10153     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10154     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10155     ds_pool_ci.maxSets = 1;
10156     ds_pool_ci.poolSizeCount = 1;
10157     ds_pool_ci.pPoolSizes = &ds_type_count;
10158
10159     VkDescriptorPool ds_pool;
10160     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10161     ASSERT_VK_SUCCESS(err);
10162
10163     VkDescriptorSetLayoutBinding dsl_binding = {};
10164     dsl_binding.binding = 0;
10165     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10166     dsl_binding.descriptorCount = 1;
10167     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10168
10169     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10170     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10171     ds_layout_ci.bindingCount = 1;
10172     ds_layout_ci.pBindings = &dsl_binding;
10173
10174     VkDescriptorSetLayout ds_layout;
10175     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10176     ASSERT_VK_SUCCESS(err);
10177
10178     VkDescriptorSet descriptorSet;
10179     VkDescriptorSetAllocateInfo alloc_info = {};
10180     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10181     alloc_info.descriptorSetCount = 1;
10182     alloc_info.descriptorPool = ds_pool;
10183     alloc_info.pSetLayouts = &ds_layout;
10184     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10185     ASSERT_VK_SUCCESS(err);
10186
10187     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10188     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10189     pipeline_layout_ci.setLayoutCount = 1;
10190     pipeline_layout_ci.pSetLayouts = &ds_layout;
10191
10192     VkPipelineLayout pipeline_layout;
10193     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10194     ASSERT_VK_SUCCESS(err);
10195
10196     VkPipelineViewportStateCreateInfo vp_state_ci = {};
10197     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10198     vp_state_ci.scissorCount = 1;
10199     vp_state_ci.pScissors = NULL;
10200     vp_state_ci.viewportCount = 1;
10201     vp_state_ci.pViewports = NULL;
10202
10203     VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
10204     // Set scissor as dynamic to avoid that error
10205     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10206     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10207     dyn_state_ci.dynamicStateCount = 2;
10208     dyn_state_ci.pDynamicStates = dynamic_states;
10209
10210     VkPipelineShaderStageCreateInfo shaderStages[2];
10211     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10212
10213     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10214     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
10215                    this); // TODO - We shouldn't need a fragment shader
10216                           // but add it to be able to run on more devices
10217     shaderStages[0] = vs.GetStageCreateInfo();
10218     shaderStages[1] = fs.GetStageCreateInfo();
10219
10220     VkPipelineVertexInputStateCreateInfo vi_ci = {};
10221     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10222     vi_ci.pNext = nullptr;
10223     vi_ci.vertexBindingDescriptionCount = 0;
10224     vi_ci.pVertexBindingDescriptions = nullptr;
10225     vi_ci.vertexAttributeDescriptionCount = 0;
10226     vi_ci.pVertexAttributeDescriptions = nullptr;
10227
10228     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10229     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10230     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10231
10232     VkPipelineRasterizationStateCreateInfo rs_ci = {};
10233     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10234     rs_ci.pNext = nullptr;
10235
10236     // Check too low (line width of -1.0f).
10237     rs_ci.lineWidth = -1.0f;
10238
10239     VkPipelineColorBlendAttachmentState att = {};
10240     att.blendEnable = VK_FALSE;
10241     att.colorWriteMask = 0xf;
10242
10243     VkPipelineColorBlendStateCreateInfo cb_ci = {};
10244     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10245     cb_ci.pNext = nullptr;
10246     cb_ci.attachmentCount = 1;
10247     cb_ci.pAttachments = &att;
10248
10249     VkGraphicsPipelineCreateInfo gp_ci = {};
10250     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10251     gp_ci.stageCount = 2;
10252     gp_ci.pStages = shaderStages;
10253     gp_ci.pVertexInputState = &vi_ci;
10254     gp_ci.pInputAssemblyState = &ia_ci;
10255     gp_ci.pViewportState = &vp_state_ci;
10256     gp_ci.pRasterizationState = &rs_ci;
10257     gp_ci.pColorBlendState = &cb_ci;
10258     gp_ci.pDynamicState = &dyn_state_ci;
10259     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10260     gp_ci.layout = pipeline_layout;
10261     gp_ci.renderPass = renderPass();
10262
10263     VkPipelineCacheCreateInfo pc_ci = {};
10264     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10265
10266     VkPipeline pipeline;
10267     VkPipelineCache pipelineCache;
10268
10269     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10270     ASSERT_VK_SUCCESS(err);
10271     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10272
10273     m_errorMonitor->VerifyFound();
10274     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10275
10276     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10277
10278     // Check too high (line width of 65536.0f).
10279     rs_ci.lineWidth = 65536.0f;
10280
10281     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10282     ASSERT_VK_SUCCESS(err);
10283     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10284
10285     m_errorMonitor->VerifyFound();
10286     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10287
10288     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10289
10290     dyn_state_ci.dynamicStateCount = 3;
10291
10292     rs_ci.lineWidth = 1.0f;
10293
10294     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10295     ASSERT_VK_SUCCESS(err);
10296     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10297     BeginCommandBuffer();
10298     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10299
10300     // Check too low with dynamic setting.
10301     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f);
10302     m_errorMonitor->VerifyFound();
10303
10304     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10305
10306     // Check too high with dynamic setting.
10307     vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f);
10308     m_errorMonitor->VerifyFound();
10309     EndCommandBuffer();
10310
10311     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10312     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10313     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10314     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10315     vkDestroyPipeline(m_device->device(), pipeline, NULL);
10316 }
10317
10318 TEST_F(VkLayerTest, NullRenderPass) {
10319     // Bind a NULL RenderPass
10320     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10321                                          "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
10322
10323     ASSERT_NO_FATAL_FAILURE(InitState());
10324     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10325
10326     BeginCommandBuffer();
10327     // Don't care about RenderPass handle b/c error should be flagged before
10328     // that
10329     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
10330
10331     m_errorMonitor->VerifyFound();
10332 }
10333
10334 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
10335     // Bind a BeginRenderPass within an active RenderPass
10336     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10337                                          "It is invalid to issue this call inside an active render pass");
10338
10339     ASSERT_NO_FATAL_FAILURE(InitState());
10340     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10341
10342     BeginCommandBuffer();
10343     // Just create a dummy Renderpass that's non-NULL so we can get to the
10344     // proper error
10345     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10346
10347     m_errorMonitor->VerifyFound();
10348 }
10349
10350 TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
10351     m_errorMonitor->ExpectSuccess();
10352
10353     ASSERT_NO_FATAL_FAILURE(InitState());
10354     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10355
10356     BeginCommandBuffer();                                   // framework implicitly begins the renderpass.
10357     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
10358
10359     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
10360     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10361     m_errorMonitor->VerifyNotFound();
10362     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10363     m_errorMonitor->VerifyNotFound();
10364     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10365     m_errorMonitor->VerifyNotFound();
10366
10367     m_commandBuffer->EndCommandBuffer();
10368     m_errorMonitor->VerifyNotFound();
10369 }
10370
10371 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
10372     TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
10373                      "the number of renderPass attachments that use loadOp"
10374                      "VK_ATTACHMENT_LOAD_OP_CLEAR.");
10375
10376     ASSERT_NO_FATAL_FAILURE(InitState());
10377     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10378
10379     // Create a renderPass with a single attachment that uses loadOp CLEAR
10380     VkAttachmentReference attach = {};
10381     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
10382     VkSubpassDescription subpass = {};
10383     subpass.inputAttachmentCount = 1;
10384     subpass.pInputAttachments = &attach;
10385     VkRenderPassCreateInfo rpci = {};
10386     rpci.subpassCount = 1;
10387     rpci.pSubpasses = &subpass;
10388     rpci.attachmentCount = 1;
10389     VkAttachmentDescription attach_desc = {};
10390     attach_desc.format = VK_FORMAT_UNDEFINED;
10391     // Set loadOp to CLEAR
10392     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10393     rpci.pAttachments = &attach_desc;
10394     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10395     VkRenderPass rp;
10396     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
10397
10398     VkCommandBufferInheritanceInfo hinfo = {};
10399     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10400     hinfo.renderPass = VK_NULL_HANDLE;
10401     hinfo.subpass = 0;
10402     hinfo.framebuffer = VK_NULL_HANDLE;
10403     hinfo.occlusionQueryEnable = VK_FALSE;
10404     hinfo.queryFlags = 0;
10405     hinfo.pipelineStatistics = 0;
10406     VkCommandBufferBeginInfo info = {};
10407     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
10408     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10409     info.pInheritanceInfo = &hinfo;
10410
10411     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
10412     VkRenderPassBeginInfo rp_begin = {};
10413     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
10414     rp_begin.pNext = NULL;
10415     rp_begin.renderPass = renderPass();
10416     rp_begin.framebuffer = framebuffer();
10417     rp_begin.clearValueCount = 0; // Should be 1
10418
10419     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but "
10420                                                                         "there must be at least 1 entries in "
10421                                                                         "pClearValues array to account for ");
10422
10423     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
10424
10425     m_errorMonitor->VerifyFound();
10426
10427     vkDestroyRenderPass(m_device->device(), rp, NULL);
10428 }
10429
10430 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
10431
10432     TEST_DESCRIPTION("End a command buffer with an active render pass");
10433
10434     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10435                                          "It is invalid to issue this call inside an active render pass");
10436
10437     ASSERT_NO_FATAL_FAILURE(InitState());
10438     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10439
10440     // The framework's BeginCommandBuffer calls CreateRenderPass
10441     BeginCommandBuffer();
10442
10443     // Call directly into vkEndCommandBuffer instead of the
10444     // the framework's EndCommandBuffer, which inserts a
10445     // vkEndRenderPass
10446     vkEndCommandBuffer(m_commandBuffer->GetBufferHandle());
10447
10448     m_errorMonitor->VerifyFound();
10449
10450     // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
10451     // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
10452 }
10453
10454 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
10455     // Call CmdFillBuffer within an active renderpass
10456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10457                                          "It is invalid to issue this call inside an active render pass");
10458
10459     ASSERT_NO_FATAL_FAILURE(InitState());
10460     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10461
10462     // Renderpass is started here
10463     BeginCommandBuffer();
10464
10465     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10466     vk_testing::Buffer dstBuffer;
10467     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10468
10469     m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
10470
10471     m_errorMonitor->VerifyFound();
10472 }
10473
10474 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
10475     // Call CmdUpdateBuffer within an active renderpass
10476     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10477                                          "It is invalid to issue this call inside an active render pass");
10478
10479     ASSERT_NO_FATAL_FAILURE(InitState());
10480     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10481
10482     // Renderpass is started here
10483     BeginCommandBuffer();
10484
10485     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10486     vk_testing::Buffer dstBuffer;
10487     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10488
10489     VkDeviceSize dstOffset = 0;
10490     VkDeviceSize dataSize = 1024;
10491     const void *pData = NULL;
10492
10493     vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData);
10494
10495     m_errorMonitor->VerifyFound();
10496 }
10497
10498 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
10499     // Call CmdClearColorImage within an active RenderPass
10500     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10501                                          "It is invalid to issue this call inside an active render pass");
10502
10503     ASSERT_NO_FATAL_FAILURE(InitState());
10504     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10505
10506     // Renderpass is started here
10507     BeginCommandBuffer();
10508
10509     VkClearColorValue clear_color;
10510     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
10511     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10512     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10513     const int32_t tex_width = 32;
10514     const int32_t tex_height = 32;
10515     VkImageCreateInfo image_create_info = {};
10516     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10517     image_create_info.pNext = NULL;
10518     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10519     image_create_info.format = tex_format;
10520     image_create_info.extent.width = tex_width;
10521     image_create_info.extent.height = tex_height;
10522     image_create_info.extent.depth = 1;
10523     image_create_info.mipLevels = 1;
10524     image_create_info.arrayLayers = 1;
10525     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10526     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
10527     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10528
10529     vk_testing::Image dstImage;
10530     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10531
10532     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
10533
10534     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
10535
10536     m_errorMonitor->VerifyFound();
10537 }
10538
10539 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) {
10540     // Call CmdClearDepthStencilImage within an active RenderPass
10541     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10542                                          "It is invalid to issue this call inside an active render pass");
10543
10544     ASSERT_NO_FATAL_FAILURE(InitState());
10545     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10546
10547     // Renderpass is started here
10548     BeginCommandBuffer();
10549
10550     VkClearDepthStencilValue clear_value = {0};
10551     VkMemoryPropertyFlags reqs = 0;
10552     VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
10553     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10554     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
10555     image_create_info.extent.width = 64;
10556     image_create_info.extent.height = 64;
10557     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10558     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
10559
10560     vk_testing::Image dstImage;
10561     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10562
10563     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
10564
10565     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(),
10566                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range);
10567
10568     m_errorMonitor->VerifyFound();
10569 }
10570
10571 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
10572     // Call CmdClearAttachmentss outside of an active RenderPass
10573     VkResult err;
10574
10575     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call "
10576                                                                         "must be issued inside an active "
10577                                                                         "render pass");
10578
10579     ASSERT_NO_FATAL_FAILURE(InitState());
10580     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10581
10582     // Start no RenderPass
10583     err = m_commandBuffer->BeginCommandBuffer();
10584     ASSERT_VK_SUCCESS(err);
10585
10586     VkClearAttachment color_attachment;
10587     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10588     color_attachment.clearValue.color.float32[0] = 0;
10589     color_attachment.clearValue.color.float32[1] = 0;
10590     color_attachment.clearValue.color.float32[2] = 0;
10591     color_attachment.clearValue.color.float32[3] = 0;
10592     color_attachment.colorAttachment = 0;
10593     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
10594     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
10595
10596     m_errorMonitor->VerifyFound();
10597 }
10598
10599 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
10600     TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is "
10601                      "called too many times in a renderpass instance");
10602
10603     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance "
10604                                                                         "beyond final subpass");
10605
10606     ASSERT_NO_FATAL_FAILURE(InitState());
10607     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10608
10609     BeginCommandBuffer();
10610
10611     // error here.
10612     vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE);
10613     m_errorMonitor->VerifyFound();
10614
10615     EndCommandBuffer();
10616 }
10617
10618 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
10619     TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is "
10620                      "called before the final subpass has been reached");
10621
10622     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching "
10623                                                                         "final subpass");
10624
10625     ASSERT_NO_FATAL_FAILURE(InitState());
10626     VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
10627                                   {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
10628
10629     VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
10630
10631     VkRenderPass rp;
10632     VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
10633     ASSERT_VK_SUCCESS(err);
10634
10635     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
10636
10637     VkFramebuffer fb;
10638     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
10639     ASSERT_VK_SUCCESS(err);
10640
10641     m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin
10642
10643     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
10644
10645     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
10646
10647     // Error here.
10648     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10649     m_errorMonitor->VerifyFound();
10650
10651     // Clean up.
10652     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
10653     vkDestroyRenderPass(m_device->device(), rp, nullptr);
10654 }
10655
10656 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
10657     // Try to add a buffer memory barrier with no buffer.
10658     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10659                                          "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
10660
10661     ASSERT_NO_FATAL_FAILURE(InitState());
10662     BeginCommandBuffer();
10663
10664     VkBufferMemoryBarrier buf_barrier = {};
10665     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10666     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10667     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10668     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10669     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10670     buf_barrier.buffer = VK_NULL_HANDLE;
10671     buf_barrier.offset = 0;
10672     buf_barrier.size = VK_WHOLE_SIZE;
10673     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10674                          nullptr, 1, &buf_barrier, 0, nullptr);
10675
10676     m_errorMonitor->VerifyFound();
10677 }
10678
10679 TEST_F(VkLayerTest, InvalidBarriers) {
10680     TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
10681
10682     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass");
10683
10684     ASSERT_NO_FATAL_FAILURE(InitState());
10685     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10686
10687     VkMemoryBarrier mem_barrier = {};
10688     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
10689     mem_barrier.pNext = NULL;
10690     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10691     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10692     BeginCommandBuffer();
10693     // BeginCommandBuffer() starts a render pass
10694     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
10695                          &mem_barrier, 0, nullptr, 0, nullptr);
10696     m_errorMonitor->VerifyFound();
10697
10698     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
10699     VkImageObj image(m_device);
10700     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10701     ASSERT_TRUE(image.initialized());
10702     VkImageMemoryBarrier img_barrier = {};
10703     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10704     img_barrier.pNext = NULL;
10705     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10706     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10707     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10708     // New layout can't be UNDEFINED
10709     img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10710     img_barrier.image = image.handle();
10711     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10712     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10713     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10714     img_barrier.subresourceRange.baseArrayLayer = 0;
10715     img_barrier.subresourceRange.baseMipLevel = 0;
10716     img_barrier.subresourceRange.layerCount = 1;
10717     img_barrier.subresourceRange.levelCount = 1;
10718     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10719                          nullptr, 0, nullptr, 1, &img_barrier);
10720     m_errorMonitor->VerifyFound();
10721     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10722
10723     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the "
10724                                                                         "baseArrayLayer");
10725     // baseArrayLayer + layerCount must be <= image's arrayLayers
10726     img_barrier.subresourceRange.baseArrayLayer = 1;
10727     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10728                          nullptr, 0, nullptr, 1, &img_barrier);
10729     m_errorMonitor->VerifyFound();
10730     img_barrier.subresourceRange.baseArrayLayer = 0;
10731
10732     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel");
10733     // baseMipLevel + levelCount must be <= image's mipLevels
10734     img_barrier.subresourceRange.baseMipLevel = 1;
10735     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10736                          nullptr, 0, nullptr, 1, &img_barrier);
10737     m_errorMonitor->VerifyFound();
10738     img_barrier.subresourceRange.baseMipLevel = 0;
10739
10740     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
10741     vk_testing::Buffer buffer;
10742     buffer.init(*m_device, 256);
10743     VkBufferMemoryBarrier buf_barrier = {};
10744     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10745     buf_barrier.pNext = NULL;
10746     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10747     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10748     buf_barrier.buffer = buffer.handle();
10749     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10750     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10751     buf_barrier.offset = 0;
10752     buf_barrier.size = VK_WHOLE_SIZE;
10753     // Can't send buffer barrier during a render pass
10754     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10755                          nullptr, 1, &buf_barrier, 0, nullptr);
10756     m_errorMonitor->VerifyFound();
10757     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10758
10759     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
10760     buf_barrier.offset = 257;
10761     // Offset greater than total size
10762     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10763                          nullptr, 1, &buf_barrier, 0, nullptr);
10764     m_errorMonitor->VerifyFound();
10765     buf_barrier.offset = 0;
10766
10767     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
10768     buf_barrier.size = 257;
10769     // Size greater than total size
10770     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10771                          nullptr, 1, &buf_barrier, 0, nullptr);
10772     m_errorMonitor->VerifyFound();
10773
10774     // Now exercise barrier aspect bit errors, first DS
10775     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must "
10776                                                                         "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
10777                                                                         "VK_IMAGE_ASPECT_STENCIL_BIT set.");
10778     VkDepthStencilObj ds_image(m_device);
10779     ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
10780     ASSERT_TRUE(ds_image.initialized());
10781     img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10782     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10783     img_barrier.image = ds_image.handle();
10784     // Use of COLOR aspect on DS image is error
10785     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10786     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10787                          nullptr, 0, nullptr, 1, &img_barrier);
10788     m_errorMonitor->VerifyFound();
10789     // Now test depth-only
10790     VkFormatProperties format_props;
10791
10792     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
10793     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10794         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must "
10795                                                                             "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
10796         VkDepthStencilObj d_image(m_device);
10797         d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
10798         ASSERT_TRUE(d_image.initialized());
10799         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10800         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10801         img_barrier.image = d_image.handle();
10802         // Use of COLOR aspect on depth image is error
10803         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10804         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10805                              0, nullptr, 0, nullptr, 1, &img_barrier);
10806         m_errorMonitor->VerifyFound();
10807     }
10808     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
10809     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10810         // Now test stencil-only
10811         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must "
10812                                                                             "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
10813         VkDepthStencilObj s_image(m_device);
10814         s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
10815         ASSERT_TRUE(s_image.initialized());
10816         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10817         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10818         img_barrier.image = s_image.handle();
10819         // Use of COLOR aspect on depth image is error
10820         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10821         vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10822                              0, nullptr, 0, nullptr, 1, &img_barrier);
10823         m_errorMonitor->VerifyFound();
10824     }
10825     // Finally test color
10826     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
10827                                                                         "have VK_IMAGE_ASPECT_COLOR_BIT set.");
10828     VkImageObj c_image(m_device);
10829     c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10830     ASSERT_TRUE(c_image.initialized());
10831     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10832     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10833     img_barrier.image = c_image.handle();
10834     // Set aspect to depth (non-color)
10835     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
10836     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10837                          nullptr, 0, nullptr, 1, &img_barrier);
10838     m_errorMonitor->VerifyFound();
10839 }
10840
10841 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
10842     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
10843
10844     m_errorMonitor->SetDesiredFailureMsg(
10845         VK_DEBUG_REPORT_WARNING_BIT_EXT,
10846         "must have required access bit");
10847     ASSERT_NO_FATAL_FAILURE(InitState());
10848     VkImageObj image(m_device);
10849     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10850     ASSERT_TRUE(image.initialized());
10851
10852     VkImageMemoryBarrier barrier = {};
10853     VkImageSubresourceRange range;
10854     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10855     barrier.srcAccessMask = 0;
10856     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
10857     barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
10858     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10859     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10860     barrier.image = image.handle();
10861     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10862     range.baseMipLevel = 0;
10863     range.levelCount = 1;
10864     range.baseArrayLayer = 0;
10865     range.layerCount = 1;
10866     barrier.subresourceRange = range;
10867     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
10868     cmdbuf.BeginCommandBuffer();
10869     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10870                            &barrier);
10871     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10872     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10873     barrier.srcAccessMask = 0;
10874     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
10875     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10876                            &barrier);
10877
10878     m_errorMonitor->VerifyFound();
10879 }
10880
10881 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
10882     // Bind a BeginRenderPass within an active RenderPass
10883     VkResult err;
10884
10885     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
10886
10887     ASSERT_NO_FATAL_FAILURE(InitState());
10888     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10889     uint32_t qfi = 0;
10890     VkBufferCreateInfo buffCI = {};
10891     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10892     buffCI.size = 1024;
10893     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10894     buffCI.queueFamilyIndexCount = 1;
10895     buffCI.pQueueFamilyIndices = &qfi;
10896
10897     VkBuffer ib;
10898     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10899     ASSERT_VK_SUCCESS(err);
10900
10901     BeginCommandBuffer();
10902     ASSERT_VK_SUCCESS(err);
10903     // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
10904     // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10905     // Should error before calling to driver so don't care about actual data
10906     vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16);
10907
10908     m_errorMonitor->VerifyFound();
10909
10910     vkDestroyBuffer(m_device->device(), ib, NULL);
10911 }
10912
10913 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
10914     // Create an out-of-range queueFamilyIndex
10915     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10916                                          "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one "
10917                                          "of the indices specified when the device was created, via the "
10918                                          "VkDeviceQueueCreateInfo structure.");
10919
10920     ASSERT_NO_FATAL_FAILURE(InitState());
10921     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10922     VkBufferCreateInfo buffCI = {};
10923     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10924     buffCI.size = 1024;
10925     buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10926     buffCI.queueFamilyIndexCount = 1;
10927     // Introduce failure by specifying invalid queue_family_index
10928     uint32_t qfi = 777;
10929     buffCI.pQueueFamilyIndices = &qfi;
10930     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
10931
10932     VkBuffer ib;
10933     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10934
10935     m_errorMonitor->VerifyFound();
10936     vkDestroyBuffer(m_device->device(), ib, NULL);
10937 }
10938
10939 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
10940     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
10941                      " (should only be secondary)");
10942
10943     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
10944
10945     ASSERT_NO_FATAL_FAILURE(InitState());
10946     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10947
10948     BeginCommandBuffer();
10949
10950     VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
10951     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
10952
10953     m_errorMonitor->VerifyFound();
10954 }
10955
10956 TEST_F(VkLayerTest, DSUsageBitsErrors) {
10957     TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
10958                      "that do not have correct usage bits sets.");
10959     VkResult err;
10960
10961     ASSERT_NO_FATAL_FAILURE(InitState());
10962     VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10963     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10964         ds_type_count[i].type = VkDescriptorType(i);
10965         ds_type_count[i].descriptorCount = 1;
10966     }
10967     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10968     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10969     ds_pool_ci.pNext = NULL;
10970     ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10971     ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10972     ds_pool_ci.pPoolSizes = ds_type_count;
10973
10974     VkDescriptorPool ds_pool;
10975     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10976     ASSERT_VK_SUCCESS(err);
10977
10978     // Create 10 layouts where each has a single descriptor of different type
10979     VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10980     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10981         dsl_binding[i].binding = 0;
10982         dsl_binding[i].descriptorType = VkDescriptorType(i);
10983         dsl_binding[i].descriptorCount = 1;
10984         dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
10985         dsl_binding[i].pImmutableSamplers = NULL;
10986     }
10987
10988     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10989     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10990     ds_layout_ci.pNext = NULL;
10991     ds_layout_ci.bindingCount = 1;
10992     VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
10993     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10994         ds_layout_ci.pBindings = dsl_binding + i;
10995         err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i);
10996         ASSERT_VK_SUCCESS(err);
10997     }
10998     VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10999     VkDescriptorSetAllocateInfo alloc_info = {};
11000     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11001     alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
11002     alloc_info.descriptorPool = ds_pool;
11003     alloc_info.pSetLayouts = ds_layouts;
11004     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
11005     ASSERT_VK_SUCCESS(err);
11006
11007     // Create a buffer & bufferView to be used for invalid updates
11008     VkBufferCreateInfo buff_ci = {};
11009     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11010     // This usage is not valid for any descriptor type
11011     buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
11012     buff_ci.size = 256;
11013     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11014     VkBuffer buffer;
11015     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11016     ASSERT_VK_SUCCESS(err);
11017
11018     VkBufferViewCreateInfo buff_view_ci = {};
11019     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11020     buff_view_ci.buffer = buffer;
11021     buff_view_ci.format = VK_FORMAT_R8_UNORM;
11022     buff_view_ci.range = VK_WHOLE_SIZE;
11023     VkBufferView buff_view;
11024     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11025     ASSERT_VK_SUCCESS(err);
11026
11027     // Create an image to be used for invalid updates
11028     VkImageCreateInfo image_ci = {};
11029     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11030     image_ci.imageType = VK_IMAGE_TYPE_2D;
11031     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11032     image_ci.extent.width = 64;
11033     image_ci.extent.height = 64;
11034     image_ci.extent.depth = 1;
11035     image_ci.mipLevels = 1;
11036     image_ci.arrayLayers = 1;
11037     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11038     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11039     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11040     // This usage is not valid for any descriptor type
11041     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11042     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11043     VkImage image;
11044     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11045     ASSERT_VK_SUCCESS(err);
11046     // Bind memory to image
11047     VkMemoryRequirements mem_reqs;
11048     VkDeviceMemory image_mem;
11049     bool pass;
11050     VkMemoryAllocateInfo mem_alloc = {};
11051     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11052     mem_alloc.pNext = NULL;
11053     mem_alloc.allocationSize = 0;
11054     mem_alloc.memoryTypeIndex = 0;
11055     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11056     mem_alloc.allocationSize = mem_reqs.size;
11057     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11058     ASSERT_TRUE(pass);
11059     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11060     ASSERT_VK_SUCCESS(err);
11061     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11062     ASSERT_VK_SUCCESS(err);
11063     // Now create view for image
11064     VkImageViewCreateInfo image_view_ci = {};
11065     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11066     image_view_ci.image = image;
11067     image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11068     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11069     image_view_ci.subresourceRange.layerCount = 1;
11070     image_view_ci.subresourceRange.baseArrayLayer = 0;
11071     image_view_ci.subresourceRange.levelCount = 1;
11072     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11073     VkImageView image_view;
11074     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11075     ASSERT_VK_SUCCESS(err);
11076
11077     VkDescriptorBufferInfo buff_info = {};
11078     buff_info.buffer = buffer;
11079     VkDescriptorImageInfo img_info = {};
11080     img_info.imageView = image_view;
11081     VkWriteDescriptorSet descriptor_write = {};
11082     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11083     descriptor_write.dstBinding = 0;
11084     descriptor_write.descriptorCount = 1;
11085     descriptor_write.pTexelBufferView = &buff_view;
11086     descriptor_write.pBufferInfo = &buff_info;
11087     descriptor_write.pImageInfo = &img_info;
11088
11089     // These error messages align with VkDescriptorType struct
11090     const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor
11091                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11092                                 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11093                                 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
11094                                 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
11095                                 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
11096                                 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11097                                 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11098                                 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11099                                 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11100                                 " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
11101     // Start loop at 1 as SAMPLER desc type has no usage bit error
11102     for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
11103         descriptor_write.descriptorType = VkDescriptorType(i);
11104         descriptor_write.dstSet = descriptor_sets[i];
11105         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]);
11106
11107         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11108
11109         m_errorMonitor->VerifyFound();
11110         vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
11111     }
11112     vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
11113     vkDestroyImage(m_device->device(), image, NULL);
11114     vkFreeMemory(m_device->device(), image_mem, NULL);
11115     vkDestroyImageView(m_device->device(), image_view, NULL);
11116     vkDestroyBuffer(m_device->device(), buffer, NULL);
11117     vkDestroyBufferView(m_device->device(), buff_view, NULL);
11118     vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
11119     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11120 }
11121
11122 TEST_F(VkLayerTest, DSBufferInfoErrors) {
11123     TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect "
11124                      "parameters in VkDescriptorBufferInfo struct. This includes:\n"
11125                      "1. offset value greater than buffer size\n"
11126                      "2. range value of 0\n"
11127                      "3. range value greater than buffer (size - offset)");
11128     VkResult err;
11129
11130     ASSERT_NO_FATAL_FAILURE(InitState());
11131     VkDescriptorPoolSize ds_type_count = {};
11132     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11133     ds_type_count.descriptorCount = 1;
11134
11135     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11136     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11137     ds_pool_ci.pNext = NULL;
11138     ds_pool_ci.maxSets = 1;
11139     ds_pool_ci.poolSizeCount = 1;
11140     ds_pool_ci.pPoolSizes = &ds_type_count;
11141
11142     VkDescriptorPool ds_pool;
11143     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11144     ASSERT_VK_SUCCESS(err);
11145
11146     // Create layout with single uniform buffer descriptor
11147     VkDescriptorSetLayoutBinding dsl_binding = {};
11148     dsl_binding.binding = 0;
11149     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11150     dsl_binding.descriptorCount = 1;
11151     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11152     dsl_binding.pImmutableSamplers = NULL;
11153
11154     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11155     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11156     ds_layout_ci.pNext = NULL;
11157     ds_layout_ci.bindingCount = 1;
11158     ds_layout_ci.pBindings = &dsl_binding;
11159     VkDescriptorSetLayout ds_layout;
11160     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11161     ASSERT_VK_SUCCESS(err);
11162
11163     VkDescriptorSet descriptor_set = {};
11164     VkDescriptorSetAllocateInfo alloc_info = {};
11165     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11166     alloc_info.descriptorSetCount = 1;
11167     alloc_info.descriptorPool = ds_pool;
11168     alloc_info.pSetLayouts = &ds_layout;
11169     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11170     ASSERT_VK_SUCCESS(err);
11171
11172     // Create a buffer to be used for invalid updates
11173     VkBufferCreateInfo buff_ci = {};
11174     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11175     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
11176     buff_ci.size = 256;
11177     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11178     VkBuffer buffer;
11179     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11180     ASSERT_VK_SUCCESS(err);
11181     // Have to bind memory to buffer before descriptor update
11182     VkMemoryAllocateInfo mem_alloc = {};
11183     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11184     mem_alloc.pNext = NULL;
11185     mem_alloc.allocationSize = 256;
11186     mem_alloc.memoryTypeIndex = 0;
11187
11188     VkMemoryRequirements mem_reqs;
11189     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
11190     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11191     if (!pass) {
11192         vkDestroyBuffer(m_device->device(), buffer, NULL);
11193         return;
11194     }
11195
11196     VkDeviceMemory mem;
11197     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
11198     ASSERT_VK_SUCCESS(err);
11199     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
11200     ASSERT_VK_SUCCESS(err);
11201
11202     VkDescriptorBufferInfo buff_info = {};
11203     buff_info.buffer = buffer;
11204     // First make offset 1 larger than buffer size
11205     buff_info.offset = 257;
11206     buff_info.range = VK_WHOLE_SIZE;
11207     VkWriteDescriptorSet descriptor_write = {};
11208     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11209     descriptor_write.dstBinding = 0;
11210     descriptor_write.descriptorCount = 1;
11211     descriptor_write.pTexelBufferView = nullptr;
11212     descriptor_write.pBufferInfo = &buff_info;
11213     descriptor_write.pImageInfo = nullptr;
11214
11215     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11216     descriptor_write.dstSet = descriptor_set;
11217     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer ");
11218
11219     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11220
11221     m_errorMonitor->VerifyFound();
11222     // Now cause error due to range of 0
11223     buff_info.offset = 0;
11224     buff_info.range = 0;
11225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11226                                          " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
11227
11228     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11229
11230     m_errorMonitor->VerifyFound();
11231     // Now cause error due to range exceeding buffer size - offset
11232     buff_info.offset = 128;
11233     buff_info.range = 200;
11234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size ");
11235
11236     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11237
11238     m_errorMonitor->VerifyFound();
11239     vkFreeMemory(m_device->device(), mem, NULL);
11240     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11241     vkDestroyBuffer(m_device->device(), buffer, NULL);
11242     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11243     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11244 }
11245
11246 TEST_F(VkLayerTest, DSAspectBitsErrors) {
11247     // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
11248     //  are set, but could expand this test to hit more cases.
11249     TEST_DESCRIPTION("Attempt to update descriptor sets for images "
11250                      "that do not have correct aspect bits sets.");
11251     VkResult err;
11252
11253     ASSERT_NO_FATAL_FAILURE(InitState());
11254     VkDescriptorPoolSize ds_type_count = {};
11255     ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11256     ds_type_count.descriptorCount = 1;
11257
11258     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11259     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11260     ds_pool_ci.pNext = NULL;
11261     ds_pool_ci.maxSets = 5;
11262     ds_pool_ci.poolSizeCount = 1;
11263     ds_pool_ci.pPoolSizes = &ds_type_count;
11264
11265     VkDescriptorPool ds_pool;
11266     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11267     ASSERT_VK_SUCCESS(err);
11268
11269     VkDescriptorSetLayoutBinding dsl_binding = {};
11270     dsl_binding.binding = 0;
11271     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11272     dsl_binding.descriptorCount = 1;
11273     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11274     dsl_binding.pImmutableSamplers = NULL;
11275
11276     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11277     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11278     ds_layout_ci.pNext = NULL;
11279     ds_layout_ci.bindingCount = 1;
11280     ds_layout_ci.pBindings = &dsl_binding;
11281     VkDescriptorSetLayout ds_layout;
11282     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11283     ASSERT_VK_SUCCESS(err);
11284
11285     VkDescriptorSet descriptor_set = {};
11286     VkDescriptorSetAllocateInfo alloc_info = {};
11287     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11288     alloc_info.descriptorSetCount = 1;
11289     alloc_info.descriptorPool = ds_pool;
11290     alloc_info.pSetLayouts = &ds_layout;
11291     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11292     ASSERT_VK_SUCCESS(err);
11293
11294     // Create an image to be used for invalid updates
11295     VkImageCreateInfo image_ci = {};
11296     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11297     image_ci.imageType = VK_IMAGE_TYPE_2D;
11298     image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11299     image_ci.extent.width = 64;
11300     image_ci.extent.height = 64;
11301     image_ci.extent.depth = 1;
11302     image_ci.mipLevels = 1;
11303     image_ci.arrayLayers = 1;
11304     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11305     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11306     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11307     image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11308     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11309     VkImage image;
11310     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11311     ASSERT_VK_SUCCESS(err);
11312     // Bind memory to image
11313     VkMemoryRequirements mem_reqs;
11314     VkDeviceMemory image_mem;
11315     bool pass;
11316     VkMemoryAllocateInfo mem_alloc = {};
11317     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11318     mem_alloc.pNext = NULL;
11319     mem_alloc.allocationSize = 0;
11320     mem_alloc.memoryTypeIndex = 0;
11321     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11322     mem_alloc.allocationSize = mem_reqs.size;
11323     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11324     ASSERT_TRUE(pass);
11325     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11326     ASSERT_VK_SUCCESS(err);
11327     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11328     ASSERT_VK_SUCCESS(err);
11329     // Now create view for image
11330     VkImageViewCreateInfo image_view_ci = {};
11331     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11332     image_view_ci.image = image;
11333     image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11334     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11335     image_view_ci.subresourceRange.layerCount = 1;
11336     image_view_ci.subresourceRange.baseArrayLayer = 0;
11337     image_view_ci.subresourceRange.levelCount = 1;
11338     // Setting both depth & stencil aspect bits is illegal for descriptor
11339     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
11340
11341     VkImageView image_view;
11342     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11343     ASSERT_VK_SUCCESS(err);
11344
11345     VkDescriptorImageInfo img_info = {};
11346     img_info.imageView = image_view;
11347     VkWriteDescriptorSet descriptor_write = {};
11348     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11349     descriptor_write.dstBinding = 0;
11350     descriptor_write.descriptorCount = 1;
11351     descriptor_write.pTexelBufferView = NULL;
11352     descriptor_write.pBufferInfo = NULL;
11353     descriptor_write.pImageInfo = &img_info;
11354     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11355     descriptor_write.dstSet = descriptor_set;
11356     const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
11357                             "or VK_IMAGE_ASPECT_STENCIL_BIT ";
11358     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
11359
11360     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11361
11362     m_errorMonitor->VerifyFound();
11363     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11364     vkDestroyImage(m_device->device(), image, NULL);
11365     vkFreeMemory(m_device->device(), image_mem, NULL);
11366     vkDestroyImageView(m_device->device(), image_view, NULL);
11367     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11368     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11369 }
11370
11371 TEST_F(VkLayerTest, DSTypeMismatch) {
11372     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
11373     VkResult err;
11374
11375     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11376                                          " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update "
11377                                          "type is VK_DESCRIPTOR_TYPE_SAMPLER");
11378
11379     ASSERT_NO_FATAL_FAILURE(InitState());
11380     // VkDescriptorSetObj descriptorSet(m_device);
11381     VkDescriptorPoolSize ds_type_count = {};
11382     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11383     ds_type_count.descriptorCount = 1;
11384
11385     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11386     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11387     ds_pool_ci.pNext = NULL;
11388     ds_pool_ci.maxSets = 1;
11389     ds_pool_ci.poolSizeCount = 1;
11390     ds_pool_ci.pPoolSizes = &ds_type_count;
11391
11392     VkDescriptorPool ds_pool;
11393     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11394     ASSERT_VK_SUCCESS(err);
11395     VkDescriptorSetLayoutBinding dsl_binding = {};
11396     dsl_binding.binding = 0;
11397     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11398     dsl_binding.descriptorCount = 1;
11399     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11400     dsl_binding.pImmutableSamplers = NULL;
11401
11402     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11403     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11404     ds_layout_ci.pNext = NULL;
11405     ds_layout_ci.bindingCount = 1;
11406     ds_layout_ci.pBindings = &dsl_binding;
11407
11408     VkDescriptorSetLayout ds_layout;
11409     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11410     ASSERT_VK_SUCCESS(err);
11411
11412     VkDescriptorSet descriptorSet;
11413     VkDescriptorSetAllocateInfo alloc_info = {};
11414     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11415     alloc_info.descriptorSetCount = 1;
11416     alloc_info.descriptorPool = ds_pool;
11417     alloc_info.pSetLayouts = &ds_layout;
11418     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11419     ASSERT_VK_SUCCESS(err);
11420
11421     VkSamplerCreateInfo sampler_ci = {};
11422     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11423     sampler_ci.pNext = NULL;
11424     sampler_ci.magFilter = VK_FILTER_NEAREST;
11425     sampler_ci.minFilter = VK_FILTER_NEAREST;
11426     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11427     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11428     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11429     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11430     sampler_ci.mipLodBias = 1.0;
11431     sampler_ci.anisotropyEnable = VK_FALSE;
11432     sampler_ci.maxAnisotropy = 1;
11433     sampler_ci.compareEnable = VK_FALSE;
11434     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11435     sampler_ci.minLod = 1.0;
11436     sampler_ci.maxLod = 1.0;
11437     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11438     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11439     VkSampler sampler;
11440     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11441     ASSERT_VK_SUCCESS(err);
11442
11443     VkDescriptorImageInfo info = {};
11444     info.sampler = sampler;
11445
11446     VkWriteDescriptorSet descriptor_write;
11447     memset(&descriptor_write, 0, sizeof(descriptor_write));
11448     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11449     descriptor_write.dstSet = descriptorSet;
11450     descriptor_write.descriptorCount = 1;
11451     // This is a mismatched type for the layout which expects BUFFER
11452     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11453     descriptor_write.pImageInfo = &info;
11454
11455     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11456
11457     m_errorMonitor->VerifyFound();
11458
11459     vkDestroySampler(m_device->device(), sampler, NULL);
11460     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11461     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11462 }
11463
11464 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
11465     // For overlapping Update, have arrayIndex exceed that of layout
11466     VkResult err;
11467
11468     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11469                                          " binding #0 with 1 total descriptors but update of 1 descriptors "
11470                                          "starting at binding offset of 0 combined with update array element "
11471                                          "offset of 1 oversteps the size of this descriptor set.");
11472
11473     ASSERT_NO_FATAL_FAILURE(InitState());
11474     // VkDescriptorSetObj descriptorSet(m_device);
11475     VkDescriptorPoolSize ds_type_count = {};
11476     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11477     ds_type_count.descriptorCount = 1;
11478
11479     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11480     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11481     ds_pool_ci.pNext = NULL;
11482     ds_pool_ci.maxSets = 1;
11483     ds_pool_ci.poolSizeCount = 1;
11484     ds_pool_ci.pPoolSizes = &ds_type_count;
11485
11486     VkDescriptorPool ds_pool;
11487     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11488     ASSERT_VK_SUCCESS(err);
11489
11490     VkDescriptorSetLayoutBinding dsl_binding = {};
11491     dsl_binding.binding = 0;
11492     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11493     dsl_binding.descriptorCount = 1;
11494     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11495     dsl_binding.pImmutableSamplers = NULL;
11496
11497     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11498     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11499     ds_layout_ci.pNext = NULL;
11500     ds_layout_ci.bindingCount = 1;
11501     ds_layout_ci.pBindings = &dsl_binding;
11502
11503     VkDescriptorSetLayout ds_layout;
11504     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11505     ASSERT_VK_SUCCESS(err);
11506
11507     VkDescriptorSet descriptorSet;
11508     VkDescriptorSetAllocateInfo alloc_info = {};
11509     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11510     alloc_info.descriptorSetCount = 1;
11511     alloc_info.descriptorPool = ds_pool;
11512     alloc_info.pSetLayouts = &ds_layout;
11513     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11514     ASSERT_VK_SUCCESS(err);
11515
11516     // Correctly update descriptor to avoid "NOT_UPDATED" error
11517     VkDescriptorBufferInfo buff_info = {};
11518     buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test
11519     buff_info.offset = 0;
11520     buff_info.range = 1024;
11521
11522     VkWriteDescriptorSet descriptor_write;
11523     memset(&descriptor_write, 0, sizeof(descriptor_write));
11524     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11525     descriptor_write.dstSet = descriptorSet;
11526     descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
11527     descriptor_write.descriptorCount = 1;
11528     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11529     descriptor_write.pBufferInfo = &buff_info;
11530
11531     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11532
11533     m_errorMonitor->VerifyFound();
11534
11535     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11536     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11537 }
11538
11539 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
11540     // Create layout w/ count of 1 and attempt update to that layout w/ binding
11541     // index 2
11542     VkResult err;
11543
11544     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2.");
11545
11546     ASSERT_NO_FATAL_FAILURE(InitState());
11547     // VkDescriptorSetObj descriptorSet(m_device);
11548     VkDescriptorPoolSize ds_type_count = {};
11549     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11550     ds_type_count.descriptorCount = 1;
11551
11552     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11553     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11554     ds_pool_ci.pNext = NULL;
11555     ds_pool_ci.maxSets = 1;
11556     ds_pool_ci.poolSizeCount = 1;
11557     ds_pool_ci.pPoolSizes = &ds_type_count;
11558
11559     VkDescriptorPool ds_pool;
11560     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11561     ASSERT_VK_SUCCESS(err);
11562
11563     VkDescriptorSetLayoutBinding dsl_binding = {};
11564     dsl_binding.binding = 0;
11565     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11566     dsl_binding.descriptorCount = 1;
11567     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11568     dsl_binding.pImmutableSamplers = NULL;
11569
11570     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11571     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11572     ds_layout_ci.pNext = NULL;
11573     ds_layout_ci.bindingCount = 1;
11574     ds_layout_ci.pBindings = &dsl_binding;
11575     VkDescriptorSetLayout ds_layout;
11576     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11577     ASSERT_VK_SUCCESS(err);
11578
11579     VkDescriptorSet descriptorSet;
11580     VkDescriptorSetAllocateInfo alloc_info = {};
11581     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11582     alloc_info.descriptorSetCount = 1;
11583     alloc_info.descriptorPool = ds_pool;
11584     alloc_info.pSetLayouts = &ds_layout;
11585     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11586     ASSERT_VK_SUCCESS(err);
11587
11588     VkSamplerCreateInfo sampler_ci = {};
11589     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11590     sampler_ci.pNext = NULL;
11591     sampler_ci.magFilter = VK_FILTER_NEAREST;
11592     sampler_ci.minFilter = VK_FILTER_NEAREST;
11593     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11594     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11595     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11596     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11597     sampler_ci.mipLodBias = 1.0;
11598     sampler_ci.anisotropyEnable = VK_FALSE;
11599     sampler_ci.maxAnisotropy = 1;
11600     sampler_ci.compareEnable = VK_FALSE;
11601     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11602     sampler_ci.minLod = 1.0;
11603     sampler_ci.maxLod = 1.0;
11604     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11605     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11606
11607     VkSampler sampler;
11608     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11609     ASSERT_VK_SUCCESS(err);
11610
11611     VkDescriptorImageInfo info = {};
11612     info.sampler = sampler;
11613
11614     VkWriteDescriptorSet descriptor_write;
11615     memset(&descriptor_write, 0, sizeof(descriptor_write));
11616     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11617     descriptor_write.dstSet = descriptorSet;
11618     descriptor_write.dstBinding = 2;
11619     descriptor_write.descriptorCount = 1;
11620     // This is the wrong type, but out of bounds will be flagged first
11621     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11622     descriptor_write.pImageInfo = &info;
11623
11624     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11625
11626     m_errorMonitor->VerifyFound();
11627
11628     vkDestroySampler(m_device->device(), sampler, NULL);
11629     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11630     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11631 }
11632
11633 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
11634     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
11635     // types
11636     VkResult err;
11637
11638     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
11639
11640     ASSERT_NO_FATAL_FAILURE(InitState());
11641
11642     VkDescriptorPoolSize ds_type_count = {};
11643     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11644     ds_type_count.descriptorCount = 1;
11645
11646     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11647     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11648     ds_pool_ci.pNext = NULL;
11649     ds_pool_ci.maxSets = 1;
11650     ds_pool_ci.poolSizeCount = 1;
11651     ds_pool_ci.pPoolSizes = &ds_type_count;
11652
11653     VkDescriptorPool ds_pool;
11654     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11655     ASSERT_VK_SUCCESS(err);
11656     VkDescriptorSetLayoutBinding dsl_binding = {};
11657     dsl_binding.binding = 0;
11658     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11659     dsl_binding.descriptorCount = 1;
11660     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11661     dsl_binding.pImmutableSamplers = NULL;
11662
11663     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11664     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11665     ds_layout_ci.pNext = NULL;
11666     ds_layout_ci.bindingCount = 1;
11667     ds_layout_ci.pBindings = &dsl_binding;
11668
11669     VkDescriptorSetLayout ds_layout;
11670     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11671     ASSERT_VK_SUCCESS(err);
11672
11673     VkDescriptorSet descriptorSet;
11674     VkDescriptorSetAllocateInfo alloc_info = {};
11675     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11676     alloc_info.descriptorSetCount = 1;
11677     alloc_info.descriptorPool = ds_pool;
11678     alloc_info.pSetLayouts = &ds_layout;
11679     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11680     ASSERT_VK_SUCCESS(err);
11681
11682     VkSamplerCreateInfo sampler_ci = {};
11683     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11684     sampler_ci.pNext = NULL;
11685     sampler_ci.magFilter = VK_FILTER_NEAREST;
11686     sampler_ci.minFilter = VK_FILTER_NEAREST;
11687     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11688     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11689     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11690     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11691     sampler_ci.mipLodBias = 1.0;
11692     sampler_ci.anisotropyEnable = VK_FALSE;
11693     sampler_ci.maxAnisotropy = 1;
11694     sampler_ci.compareEnable = VK_FALSE;
11695     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11696     sampler_ci.minLod = 1.0;
11697     sampler_ci.maxLod = 1.0;
11698     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11699     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11700     VkSampler sampler;
11701     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11702     ASSERT_VK_SUCCESS(err);
11703
11704     VkDescriptorImageInfo info = {};
11705     info.sampler = sampler;
11706
11707     VkWriteDescriptorSet descriptor_write;
11708     memset(&descriptor_write, 0, sizeof(descriptor_write));
11709     descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
11710     descriptor_write.dstSet = descriptorSet;
11711     descriptor_write.descriptorCount = 1;
11712     // This is the wrong type, but out of bounds will be flagged first
11713     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11714     descriptor_write.pImageInfo = &info;
11715
11716     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11717
11718     m_errorMonitor->VerifyFound();
11719
11720     vkDestroySampler(m_device->device(), sampler, NULL);
11721     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11722     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11723 }
11724
11725 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
11726     // Create a single Sampler descriptor and send it an invalid Sampler
11727     VkResult err;
11728
11729     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11730                                          "Attempted write update to sampler descriptor with invalid sampler");
11731
11732     ASSERT_NO_FATAL_FAILURE(InitState());
11733     // TODO : Farm Descriptor setup code to helper function(s) to reduce copied
11734     // code
11735     VkDescriptorPoolSize ds_type_count = {};
11736     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
11737     ds_type_count.descriptorCount = 1;
11738
11739     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11740     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11741     ds_pool_ci.pNext = NULL;
11742     ds_pool_ci.maxSets = 1;
11743     ds_pool_ci.poolSizeCount = 1;
11744     ds_pool_ci.pPoolSizes = &ds_type_count;
11745
11746     VkDescriptorPool ds_pool;
11747     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11748     ASSERT_VK_SUCCESS(err);
11749
11750     VkDescriptorSetLayoutBinding dsl_binding = {};
11751     dsl_binding.binding = 0;
11752     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11753     dsl_binding.descriptorCount = 1;
11754     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11755     dsl_binding.pImmutableSamplers = NULL;
11756
11757     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11758     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11759     ds_layout_ci.pNext = NULL;
11760     ds_layout_ci.bindingCount = 1;
11761     ds_layout_ci.pBindings = &dsl_binding;
11762     VkDescriptorSetLayout ds_layout;
11763     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11764     ASSERT_VK_SUCCESS(err);
11765
11766     VkDescriptorSet descriptorSet;
11767     VkDescriptorSetAllocateInfo alloc_info = {};
11768     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11769     alloc_info.descriptorSetCount = 1;
11770     alloc_info.descriptorPool = ds_pool;
11771     alloc_info.pSetLayouts = &ds_layout;
11772     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11773     ASSERT_VK_SUCCESS(err);
11774
11775     VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle
11776
11777     VkDescriptorImageInfo descriptor_info;
11778     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11779     descriptor_info.sampler = sampler;
11780
11781     VkWriteDescriptorSet descriptor_write;
11782     memset(&descriptor_write, 0, sizeof(descriptor_write));
11783     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11784     descriptor_write.dstSet = descriptorSet;
11785     descriptor_write.dstBinding = 0;
11786     descriptor_write.descriptorCount = 1;
11787     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11788     descriptor_write.pImageInfo = &descriptor_info;
11789
11790     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11791
11792     m_errorMonitor->VerifyFound();
11793
11794     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11795     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11796 }
11797
11798 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
11799     // Create a single combined Image/Sampler descriptor and send it an invalid
11800     // imageView
11801     VkResult err;
11802
11803     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined "
11804                                                                         "image sampler descriptor failed due "
11805                                                                         "to: Invalid VkImageView:");
11806
11807     ASSERT_NO_FATAL_FAILURE(InitState());
11808     VkDescriptorPoolSize ds_type_count = {};
11809     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11810     ds_type_count.descriptorCount = 1;
11811
11812     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11813     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11814     ds_pool_ci.pNext = NULL;
11815     ds_pool_ci.maxSets = 1;
11816     ds_pool_ci.poolSizeCount = 1;
11817     ds_pool_ci.pPoolSizes = &ds_type_count;
11818
11819     VkDescriptorPool ds_pool;
11820     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11821     ASSERT_VK_SUCCESS(err);
11822
11823     VkDescriptorSetLayoutBinding dsl_binding = {};
11824     dsl_binding.binding = 0;
11825     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11826     dsl_binding.descriptorCount = 1;
11827     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11828     dsl_binding.pImmutableSamplers = NULL;
11829
11830     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11831     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11832     ds_layout_ci.pNext = NULL;
11833     ds_layout_ci.bindingCount = 1;
11834     ds_layout_ci.pBindings = &dsl_binding;
11835     VkDescriptorSetLayout ds_layout;
11836     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11837     ASSERT_VK_SUCCESS(err);
11838
11839     VkDescriptorSet descriptorSet;
11840     VkDescriptorSetAllocateInfo alloc_info = {};
11841     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11842     alloc_info.descriptorSetCount = 1;
11843     alloc_info.descriptorPool = ds_pool;
11844     alloc_info.pSetLayouts = &ds_layout;
11845     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11846     ASSERT_VK_SUCCESS(err);
11847
11848     VkSamplerCreateInfo sampler_ci = {};
11849     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11850     sampler_ci.pNext = NULL;
11851     sampler_ci.magFilter = VK_FILTER_NEAREST;
11852     sampler_ci.minFilter = VK_FILTER_NEAREST;
11853     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11854     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11855     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11856     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11857     sampler_ci.mipLodBias = 1.0;
11858     sampler_ci.anisotropyEnable = VK_FALSE;
11859     sampler_ci.maxAnisotropy = 1;
11860     sampler_ci.compareEnable = VK_FALSE;
11861     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11862     sampler_ci.minLod = 1.0;
11863     sampler_ci.maxLod = 1.0;
11864     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11865     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11866
11867     VkSampler sampler;
11868     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11869     ASSERT_VK_SUCCESS(err);
11870
11871     VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object
11872
11873     VkDescriptorImageInfo descriptor_info;
11874     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11875     descriptor_info.sampler = sampler;
11876     descriptor_info.imageView = view;
11877
11878     VkWriteDescriptorSet descriptor_write;
11879     memset(&descriptor_write, 0, sizeof(descriptor_write));
11880     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11881     descriptor_write.dstSet = descriptorSet;
11882     descriptor_write.dstBinding = 0;
11883     descriptor_write.descriptorCount = 1;
11884     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11885     descriptor_write.pImageInfo = &descriptor_info;
11886
11887     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11888
11889     m_errorMonitor->VerifyFound();
11890
11891     vkDestroySampler(m_device->device(), sampler, NULL);
11892     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11893     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11894 }
11895
11896 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
11897     // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
11898     // into the other
11899     VkResult err;
11900
11901     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type "
11902                                                                         "VK_DESCRIPTOR_TYPE_SAMPLER. Types do "
11903                                                                         "not match.");
11904
11905     ASSERT_NO_FATAL_FAILURE(InitState());
11906     // VkDescriptorSetObj descriptorSet(m_device);
11907     VkDescriptorPoolSize ds_type_count[2] = {};
11908     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11909     ds_type_count[0].descriptorCount = 1;
11910     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
11911     ds_type_count[1].descriptorCount = 1;
11912
11913     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11914     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11915     ds_pool_ci.pNext = NULL;
11916     ds_pool_ci.maxSets = 1;
11917     ds_pool_ci.poolSizeCount = 2;
11918     ds_pool_ci.pPoolSizes = ds_type_count;
11919
11920     VkDescriptorPool ds_pool;
11921     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11922     ASSERT_VK_SUCCESS(err);
11923     VkDescriptorSetLayoutBinding dsl_binding[2] = {};
11924     dsl_binding[0].binding = 0;
11925     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11926     dsl_binding[0].descriptorCount = 1;
11927     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
11928     dsl_binding[0].pImmutableSamplers = NULL;
11929     dsl_binding[1].binding = 1;
11930     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11931     dsl_binding[1].descriptorCount = 1;
11932     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
11933     dsl_binding[1].pImmutableSamplers = NULL;
11934
11935     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11936     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11937     ds_layout_ci.pNext = NULL;
11938     ds_layout_ci.bindingCount = 2;
11939     ds_layout_ci.pBindings = dsl_binding;
11940
11941     VkDescriptorSetLayout ds_layout;
11942     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11943     ASSERT_VK_SUCCESS(err);
11944
11945     VkDescriptorSet descriptorSet;
11946     VkDescriptorSetAllocateInfo alloc_info = {};
11947     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11948     alloc_info.descriptorSetCount = 1;
11949     alloc_info.descriptorPool = ds_pool;
11950     alloc_info.pSetLayouts = &ds_layout;
11951     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11952     ASSERT_VK_SUCCESS(err);
11953
11954     VkSamplerCreateInfo sampler_ci = {};
11955     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11956     sampler_ci.pNext = NULL;
11957     sampler_ci.magFilter = VK_FILTER_NEAREST;
11958     sampler_ci.minFilter = VK_FILTER_NEAREST;
11959     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11960     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11961     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11962     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11963     sampler_ci.mipLodBias = 1.0;
11964     sampler_ci.anisotropyEnable = VK_FALSE;
11965     sampler_ci.maxAnisotropy = 1;
11966     sampler_ci.compareEnable = VK_FALSE;
11967     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11968     sampler_ci.minLod = 1.0;
11969     sampler_ci.maxLod = 1.0;
11970     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11971     sampler_ci.unnormalizedCoordinates = VK_FALSE;
11972
11973     VkSampler sampler;
11974     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11975     ASSERT_VK_SUCCESS(err);
11976
11977     VkDescriptorImageInfo info = {};
11978     info.sampler = sampler;
11979
11980     VkWriteDescriptorSet descriptor_write;
11981     memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
11982     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11983     descriptor_write.dstSet = descriptorSet;
11984     descriptor_write.dstBinding = 1; // SAMPLER binding from layout above
11985     descriptor_write.descriptorCount = 1;
11986     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11987     descriptor_write.pImageInfo = &info;
11988     // This write update should succeed
11989     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11990     // Now perform a copy update that fails due to type mismatch
11991     VkCopyDescriptorSet copy_ds_update;
11992     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
11993     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
11994     copy_ds_update.srcSet = descriptorSet;
11995     copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding
11996     copy_ds_update.dstSet = descriptorSet;
11997     copy_ds_update.dstBinding = 0;      // ERROR : copy to UNIFORM binding
11998     copy_ds_update.descriptorCount = 1; // copy 1 descriptor
11999     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12000
12001     m_errorMonitor->VerifyFound();
12002     // Now perform a copy update that fails due to binding out of bounds
12003     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
12004     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12005     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12006     copy_ds_update.srcSet = descriptorSet;
12007     copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout
12008     copy_ds_update.dstSet = descriptorSet;
12009     copy_ds_update.dstBinding = 0;
12010     copy_ds_update.descriptorCount = 1; // Copy 1 descriptor
12011     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12012
12013     m_errorMonitor->VerifyFound();
12014
12015     // Now perform a copy update that fails due to binding out of bounds
12016     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus "
12017                                                                         "update array offset of 0 and update of "
12018                                                                         "5 descriptors oversteps total number "
12019                                                                         "of descriptors in set: 2.");
12020
12021     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
12022     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12023     copy_ds_update.srcSet = descriptorSet;
12024     copy_ds_update.srcBinding = 1;
12025     copy_ds_update.dstSet = descriptorSet;
12026     copy_ds_update.dstBinding = 0;
12027     copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout)
12028     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
12029
12030     m_errorMonitor->VerifyFound();
12031
12032     vkDestroySampler(m_device->device(), sampler, NULL);
12033     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12034     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12035 }
12036
12037 TEST_F(VkLayerTest, NumSamplesMismatch) {
12038     // Create CommandBuffer where MSAA samples doesn't match RenderPass
12039     // sampleCount
12040     VkResult err;
12041
12042     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
12043
12044     ASSERT_NO_FATAL_FAILURE(InitState());
12045     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12046     VkDescriptorPoolSize ds_type_count = {};
12047     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12048     ds_type_count.descriptorCount = 1;
12049
12050     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12051     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12052     ds_pool_ci.pNext = NULL;
12053     ds_pool_ci.maxSets = 1;
12054     ds_pool_ci.poolSizeCount = 1;
12055     ds_pool_ci.pPoolSizes = &ds_type_count;
12056
12057     VkDescriptorPool ds_pool;
12058     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12059     ASSERT_VK_SUCCESS(err);
12060
12061     VkDescriptorSetLayoutBinding dsl_binding = {};
12062     dsl_binding.binding = 0;
12063     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12064     dsl_binding.descriptorCount = 1;
12065     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12066     dsl_binding.pImmutableSamplers = NULL;
12067
12068     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12069     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12070     ds_layout_ci.pNext = NULL;
12071     ds_layout_ci.bindingCount = 1;
12072     ds_layout_ci.pBindings = &dsl_binding;
12073
12074     VkDescriptorSetLayout ds_layout;
12075     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12076     ASSERT_VK_SUCCESS(err);
12077
12078     VkDescriptorSet descriptorSet;
12079     VkDescriptorSetAllocateInfo alloc_info = {};
12080     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12081     alloc_info.descriptorSetCount = 1;
12082     alloc_info.descriptorPool = ds_pool;
12083     alloc_info.pSetLayouts = &ds_layout;
12084     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12085     ASSERT_VK_SUCCESS(err);
12086
12087     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12088     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12089     pipe_ms_state_ci.pNext = NULL;
12090     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12091     pipe_ms_state_ci.sampleShadingEnable = 0;
12092     pipe_ms_state_ci.minSampleShading = 1.0;
12093     pipe_ms_state_ci.pSampleMask = NULL;
12094
12095     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12096     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12097     pipeline_layout_ci.pNext = NULL;
12098     pipeline_layout_ci.setLayoutCount = 1;
12099     pipeline_layout_ci.pSetLayouts = &ds_layout;
12100
12101     VkPipelineLayout pipeline_layout;
12102     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12103     ASSERT_VK_SUCCESS(err);
12104
12105     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12106     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12107     // but add it to be able to run on more devices
12108     VkPipelineObj pipe(m_device);
12109     pipe.AddShader(&vs);
12110     pipe.AddShader(&fs);
12111     pipe.AddColorAttachment();
12112     pipe.SetMSAA(&pipe_ms_state_ci);
12113     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12114
12115     BeginCommandBuffer();
12116     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12117
12118     // Render triangle (the error should trigger on the attempt to draw).
12119     Draw(3, 1, 0, 0);
12120
12121     // Finalize recording of the command buffer
12122     EndCommandBuffer();
12123
12124     m_errorMonitor->VerifyFound();
12125
12126     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12127     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12128     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12129 }
12130
12131 TEST_F(VkLayerTest, RenderPassIncompatible) {
12132     TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
12133                      "Initial case is drawing with an active renderpass that's "
12134                      "not compatible with the bound PSO's creation renderpass");
12135     VkResult err;
12136
12137     ASSERT_NO_FATAL_FAILURE(InitState());
12138     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12139
12140     VkDescriptorSetLayoutBinding dsl_binding = {};
12141     dsl_binding.binding = 0;
12142     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12143     dsl_binding.descriptorCount = 1;
12144     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12145     dsl_binding.pImmutableSamplers = NULL;
12146
12147     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12148     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12149     ds_layout_ci.pNext = NULL;
12150     ds_layout_ci.bindingCount = 1;
12151     ds_layout_ci.pBindings = &dsl_binding;
12152
12153     VkDescriptorSetLayout ds_layout;
12154     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12155     ASSERT_VK_SUCCESS(err);
12156
12157     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12158     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12159     pipeline_layout_ci.pNext = NULL;
12160     pipeline_layout_ci.setLayoutCount = 1;
12161     pipeline_layout_ci.pSetLayouts = &ds_layout;
12162
12163     VkPipelineLayout pipeline_layout;
12164     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12165     ASSERT_VK_SUCCESS(err);
12166
12167     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12168     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12169     // but add it to be able to run on more devices
12170     // Create a renderpass that will be incompatible with default renderpass
12171     VkAttachmentReference attach = {};
12172     attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12173     VkAttachmentReference color_att = {};
12174     color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12175     VkSubpassDescription subpass = {};
12176     subpass.inputAttachmentCount = 1;
12177     subpass.pInputAttachments = &attach;
12178     subpass.colorAttachmentCount = 1;
12179     subpass.pColorAttachments = &color_att;
12180     VkRenderPassCreateInfo rpci = {};
12181     rpci.subpassCount = 1;
12182     rpci.pSubpasses = &subpass;
12183     rpci.attachmentCount = 1;
12184     VkAttachmentDescription attach_desc = {};
12185     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12186     // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
12187     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
12188     rpci.pAttachments = &attach_desc;
12189     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12190     VkRenderPass rp;
12191     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12192     VkPipelineObj pipe(m_device);
12193     pipe.AddShader(&vs);
12194     pipe.AddShader(&fs);
12195     pipe.AddColorAttachment();
12196     VkViewport view_port = {};
12197     m_viewports.push_back(view_port);
12198     pipe.SetViewport(m_viewports);
12199     VkRect2D rect = {};
12200     m_scissors.push_back(rect);
12201     pipe.SetScissor(m_scissors);
12202     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12203
12204     VkCommandBufferInheritanceInfo cbii = {};
12205     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12206     cbii.renderPass = rp;
12207     cbii.subpass = 0;
12208     VkCommandBufferBeginInfo cbbi = {};
12209     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12210     cbbi.pInheritanceInfo = &cbii;
12211     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
12212     VkRenderPassBeginInfo rpbi = {};
12213     rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
12214     rpbi.framebuffer = m_framebuffer;
12215     rpbi.renderPass = rp;
12216     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
12217     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12218
12219     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline ");
12220     // Render triangle (the error should trigger on the attempt to draw).
12221     Draw(3, 1, 0, 0);
12222
12223     // Finalize recording of the command buffer
12224     EndCommandBuffer();
12225
12226     m_errorMonitor->VerifyFound();
12227
12228     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12229     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12230     vkDestroyRenderPass(m_device->device(), rp, NULL);
12231 }
12232
12233 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
12234     // Create Pipeline where the number of blend attachments doesn't match the
12235     // number of color attachments.  In this case, we don't add any color
12236     // blend attachments even though we have a color attachment.
12237     VkResult err;
12238
12239     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12240                                          "Render pass subpass 0 mismatch with blending state defined and blend state attachment");
12241
12242     ASSERT_NO_FATAL_FAILURE(InitState());
12243     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12244     VkDescriptorPoolSize ds_type_count = {};
12245     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12246     ds_type_count.descriptorCount = 1;
12247
12248     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12249     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12250     ds_pool_ci.pNext = NULL;
12251     ds_pool_ci.maxSets = 1;
12252     ds_pool_ci.poolSizeCount = 1;
12253     ds_pool_ci.pPoolSizes = &ds_type_count;
12254
12255     VkDescriptorPool ds_pool;
12256     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12257     ASSERT_VK_SUCCESS(err);
12258
12259     VkDescriptorSetLayoutBinding dsl_binding = {};
12260     dsl_binding.binding = 0;
12261     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12262     dsl_binding.descriptorCount = 1;
12263     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12264     dsl_binding.pImmutableSamplers = NULL;
12265
12266     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12267     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12268     ds_layout_ci.pNext = NULL;
12269     ds_layout_ci.bindingCount = 1;
12270     ds_layout_ci.pBindings = &dsl_binding;
12271
12272     VkDescriptorSetLayout ds_layout;
12273     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12274     ASSERT_VK_SUCCESS(err);
12275
12276     VkDescriptorSet descriptorSet;
12277     VkDescriptorSetAllocateInfo alloc_info = {};
12278     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12279     alloc_info.descriptorSetCount = 1;
12280     alloc_info.descriptorPool = ds_pool;
12281     alloc_info.pSetLayouts = &ds_layout;
12282     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12283     ASSERT_VK_SUCCESS(err);
12284
12285     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12286     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12287     pipe_ms_state_ci.pNext = NULL;
12288     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12289     pipe_ms_state_ci.sampleShadingEnable = 0;
12290     pipe_ms_state_ci.minSampleShading = 1.0;
12291     pipe_ms_state_ci.pSampleMask = NULL;
12292
12293     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12294     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12295     pipeline_layout_ci.pNext = NULL;
12296     pipeline_layout_ci.setLayoutCount = 1;
12297     pipeline_layout_ci.pSetLayouts = &ds_layout;
12298
12299     VkPipelineLayout pipeline_layout;
12300     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12301     ASSERT_VK_SUCCESS(err);
12302
12303     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12304     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12305     // but add it to be able to run on more devices
12306     VkPipelineObj pipe(m_device);
12307     pipe.AddShader(&vs);
12308     pipe.AddShader(&fs);
12309     pipe.SetMSAA(&pipe_ms_state_ci);
12310     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12311
12312     BeginCommandBuffer();
12313     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12314
12315     // Render triangle (the error should trigger on the attempt to draw).
12316     Draw(3, 1, 0, 0);
12317
12318     // Finalize recording of the command buffer
12319     EndCommandBuffer();
12320
12321     m_errorMonitor->VerifyFound();
12322
12323     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12324     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12325     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12326 }
12327
12328 TEST_F(VkLayerTest, MissingClearAttachment) {
12329     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
12330                      "structure passed to vkCmdClearAttachments");
12331     ASSERT_NO_FATAL_FAILURE(InitState());
12332     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12333                                          "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored");
12334
12335     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
12336     m_errorMonitor->VerifyFound();
12337 }
12338
12339 TEST_F(VkLayerTest, ClearCmdNoDraw) {
12340     // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
12341     // to issuing a Draw
12342     VkResult err;
12343
12344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12345                                          "vkCmdClearAttachments() issued on CB object ");
12346
12347     ASSERT_NO_FATAL_FAILURE(InitState());
12348     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12349
12350     VkDescriptorPoolSize ds_type_count = {};
12351     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12352     ds_type_count.descriptorCount = 1;
12353
12354     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12355     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12356     ds_pool_ci.pNext = NULL;
12357     ds_pool_ci.maxSets = 1;
12358     ds_pool_ci.poolSizeCount = 1;
12359     ds_pool_ci.pPoolSizes = &ds_type_count;
12360
12361     VkDescriptorPool ds_pool;
12362     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12363     ASSERT_VK_SUCCESS(err);
12364
12365     VkDescriptorSetLayoutBinding dsl_binding = {};
12366     dsl_binding.binding = 0;
12367     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12368     dsl_binding.descriptorCount = 1;
12369     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12370     dsl_binding.pImmutableSamplers = NULL;
12371
12372     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12373     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12374     ds_layout_ci.pNext = NULL;
12375     ds_layout_ci.bindingCount = 1;
12376     ds_layout_ci.pBindings = &dsl_binding;
12377
12378     VkDescriptorSetLayout ds_layout;
12379     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12380     ASSERT_VK_SUCCESS(err);
12381
12382     VkDescriptorSet descriptorSet;
12383     VkDescriptorSetAllocateInfo alloc_info = {};
12384     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12385     alloc_info.descriptorSetCount = 1;
12386     alloc_info.descriptorPool = ds_pool;
12387     alloc_info.pSetLayouts = &ds_layout;
12388     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12389     ASSERT_VK_SUCCESS(err);
12390
12391     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12392     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12393     pipe_ms_state_ci.pNext = NULL;
12394     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12395     pipe_ms_state_ci.sampleShadingEnable = 0;
12396     pipe_ms_state_ci.minSampleShading = 1.0;
12397     pipe_ms_state_ci.pSampleMask = NULL;
12398
12399     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12400     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12401     pipeline_layout_ci.pNext = NULL;
12402     pipeline_layout_ci.setLayoutCount = 1;
12403     pipeline_layout_ci.pSetLayouts = &ds_layout;
12404
12405     VkPipelineLayout pipeline_layout;
12406     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12407     ASSERT_VK_SUCCESS(err);
12408
12409     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12410     //  We shouldn't need a fragment shader but add it to be able to run
12411     //  on more devices
12412     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12413
12414     VkPipelineObj pipe(m_device);
12415     pipe.AddShader(&vs);
12416     pipe.AddShader(&fs);
12417     pipe.SetMSAA(&pipe_ms_state_ci);
12418     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12419
12420     BeginCommandBuffer();
12421
12422     // Main thing we care about for this test is that the VkImage obj we're
12423     // clearing matches Color Attachment of FB
12424     //  Also pass down other dummy params to keep driver and paramchecker happy
12425     VkClearAttachment color_attachment;
12426     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12427     color_attachment.clearValue.color.float32[0] = 1.0;
12428     color_attachment.clearValue.color.float32[1] = 1.0;
12429     color_attachment.clearValue.color.float32[2] = 1.0;
12430     color_attachment.clearValue.color.float32[3] = 1.0;
12431     color_attachment.colorAttachment = 0;
12432     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}};
12433
12434     vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
12435
12436     m_errorMonitor->VerifyFound();
12437
12438     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12439     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12440     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12441 }
12442
12443 TEST_F(VkLayerTest, VtxBufferBadIndex) {
12444     VkResult err;
12445
12446     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12447                                          "but no vertex buffers are attached to this Pipeline State Object");
12448
12449     ASSERT_NO_FATAL_FAILURE(InitState());
12450     ASSERT_NO_FATAL_FAILURE(InitViewport());
12451     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12452
12453     VkDescriptorPoolSize ds_type_count = {};
12454     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12455     ds_type_count.descriptorCount = 1;
12456
12457     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12458     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12459     ds_pool_ci.pNext = NULL;
12460     ds_pool_ci.maxSets = 1;
12461     ds_pool_ci.poolSizeCount = 1;
12462     ds_pool_ci.pPoolSizes = &ds_type_count;
12463
12464     VkDescriptorPool ds_pool;
12465     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12466     ASSERT_VK_SUCCESS(err);
12467
12468     VkDescriptorSetLayoutBinding dsl_binding = {};
12469     dsl_binding.binding = 0;
12470     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12471     dsl_binding.descriptorCount = 1;
12472     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12473     dsl_binding.pImmutableSamplers = NULL;
12474
12475     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12476     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12477     ds_layout_ci.pNext = NULL;
12478     ds_layout_ci.bindingCount = 1;
12479     ds_layout_ci.pBindings = &dsl_binding;
12480
12481     VkDescriptorSetLayout ds_layout;
12482     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12483     ASSERT_VK_SUCCESS(err);
12484
12485     VkDescriptorSet descriptorSet;
12486     VkDescriptorSetAllocateInfo alloc_info = {};
12487     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12488     alloc_info.descriptorSetCount = 1;
12489     alloc_info.descriptorPool = ds_pool;
12490     alloc_info.pSetLayouts = &ds_layout;
12491     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12492     ASSERT_VK_SUCCESS(err);
12493
12494     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12495     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12496     pipe_ms_state_ci.pNext = NULL;
12497     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12498     pipe_ms_state_ci.sampleShadingEnable = 0;
12499     pipe_ms_state_ci.minSampleShading = 1.0;
12500     pipe_ms_state_ci.pSampleMask = NULL;
12501
12502     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12503     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12504     pipeline_layout_ci.pNext = NULL;
12505     pipeline_layout_ci.setLayoutCount = 1;
12506     pipeline_layout_ci.pSetLayouts = &ds_layout;
12507     VkPipelineLayout pipeline_layout;
12508
12509     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12510     ASSERT_VK_SUCCESS(err);
12511
12512     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12513     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12514     // but add it to be able to run on more devices
12515     VkPipelineObj pipe(m_device);
12516     pipe.AddShader(&vs);
12517     pipe.AddShader(&fs);
12518     pipe.AddColorAttachment();
12519     pipe.SetMSAA(&pipe_ms_state_ci);
12520     pipe.SetViewport(m_viewports);
12521     pipe.SetScissor(m_scissors);
12522     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12523
12524     BeginCommandBuffer();
12525     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12526     // Don't care about actual data, just need to get to draw to flag error
12527     static const float vbo_data[3] = {1.f, 0.f, 1.f};
12528     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data);
12529     BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
12530     Draw(1, 0, 0, 0);
12531
12532     m_errorMonitor->VerifyFound();
12533
12534     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12535     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12536     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12537 }
12538
12539 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
12540     TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call."
12541                      "Use invalid Queue Family Index in vkCreateDevice");
12542     ASSERT_NO_FATAL_FAILURE(InitState());
12543
12544     const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() "
12545                                          "w/ pPhysicalDeviceCount value ";
12546
12547     const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid "
12548                                                    "queueFamilyIndex ";
12549
12550     const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #";
12551
12552     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message);
12553     // The following test fails with recent NVidia drivers.
12554     // By the time core_validation is reached, the NVidia
12555     // driver has sanitized the invalid condition and core_validation
12556     // is not introduced to the failure condition. This is not the case
12557     // with AMD and Mesa drivers. Futher investigation is required
12558     //    uint32_t count = static_cast<uint32_t>(~0);
12559     //    VkPhysicalDevice physical_device;
12560     //    vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
12561     //    m_errorMonitor->VerifyFound();
12562
12563     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message);
12564     float queue_priority = 0.0;
12565
12566     VkDeviceQueueCreateInfo queue_create_info = {};
12567     queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
12568     queue_create_info.queueCount = 1;
12569     queue_create_info.pQueuePriorities = &queue_priority;
12570     queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
12571
12572     VkPhysicalDeviceFeatures features = m_device->phy().features();
12573     VkDevice testDevice;
12574     VkDeviceCreateInfo device_create_info = {};
12575     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
12576     device_create_info.queueCreateInfoCount = 1;
12577     device_create_info.pQueueCreateInfos = &queue_create_info;
12578     device_create_info.pEnabledFeatures = &features;
12579     vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12580     m_errorMonitor->VerifyFound();
12581
12582     queue_create_info.queueFamilyIndex = 1;
12583
12584     unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
12585     VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
12586     for (unsigned i = 0; i < feature_count; i++) {
12587         if (VK_FALSE == feature_array[i]) {
12588             feature_array[i] = VK_TRUE;
12589             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message);
12590             device_create_info.pEnabledFeatures = &features;
12591             vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12592             m_errorMonitor->VerifyFound();
12593             break;
12594         }
12595     }
12596 }
12597
12598 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) {
12599     TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call."
12600                      "End a command buffer with a query still in progress.");
12601
12602     const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one "
12603                                       "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both "
12604                                       "must be.";
12605
12606     const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
12607
12608     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index);
12609
12610     ASSERT_NO_FATAL_FAILURE(InitState());
12611
12612     VkEvent event;
12613     VkEventCreateInfo event_create_info{};
12614     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12615     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12616
12617     VkQueue queue = VK_NULL_HANDLE;
12618     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
12619
12620     BeginCommandBuffer();
12621
12622     VkImageObj image(m_device);
12623     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12624     ASSERT_TRUE(image.initialized());
12625     VkImageMemoryBarrier img_barrier = {};
12626     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
12627     img_barrier.pNext = NULL;
12628     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
12629     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
12630     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12631     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12632     img_barrier.image = image.handle();
12633     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
12634
12635     // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies
12636     // that layer validation catches the case when it is not.
12637     img_barrier.dstQueueFamilyIndex = 0;
12638     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12639     img_barrier.subresourceRange.baseArrayLayer = 0;
12640     img_barrier.subresourceRange.baseMipLevel = 0;
12641     img_barrier.subresourceRange.layerCount = 1;
12642     img_barrier.subresourceRange.levelCount = 1;
12643     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
12644                     nullptr, 0, nullptr, 1, &img_barrier);
12645     m_errorMonitor->VerifyFound();
12646
12647     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
12648
12649     VkQueryPool query_pool;
12650     VkQueryPoolCreateInfo query_pool_create_info = {};
12651     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
12652     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
12653     query_pool_create_info.queryCount = 1;
12654     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12655
12656     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
12657     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12658
12659     vkEndCommandBuffer(m_commandBuffer->handle());
12660     m_errorMonitor->VerifyFound();
12661
12662     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
12663     vkDestroyEvent(m_device->device(), event, nullptr);
12664 }
12665
12666 TEST_F(VkLayerTest, VertexBufferInvalid) {
12667     TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
12668                      "delete a buffer twice, use an invalid offset for each "
12669                      "buffer type, and attempt to bind a null buffer");
12670
12671     const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
12672                                                    "using deleted buffer ";
12673     const char *double_destroy_message = "Cannot free buffer 0x";
12674     const char *invalid_offset_message = "vkBindBufferMemory(): "
12675                                          "memoryOffset is 0x";
12676     const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
12677                                                         "storage memoryOffset "
12678                                                         "is 0x";
12679     const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
12680                                                       "texel memoryOffset "
12681                                                       "is 0x";
12682     const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
12683                                                         "uniform memoryOffset "
12684                                                         "is 0x";
12685     const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
12686                                            " to Bind Obj(0x";
12687     const char *free_invalid_buffer_message = "Request to delete memory "
12688                                               "object 0x";
12689
12690     ASSERT_NO_FATAL_FAILURE(InitState());
12691     ASSERT_NO_FATAL_FAILURE(InitViewport());
12692     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12693
12694     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12695     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12696     pipe_ms_state_ci.pNext = NULL;
12697     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12698     pipe_ms_state_ci.sampleShadingEnable = 0;
12699     pipe_ms_state_ci.minSampleShading = 1.0;
12700     pipe_ms_state_ci.pSampleMask = nullptr;
12701
12702     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12703     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12704     VkPipelineLayout pipeline_layout;
12705
12706     VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout);
12707     ASSERT_VK_SUCCESS(err);
12708
12709     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12710     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12711     VkPipelineObj pipe(m_device);
12712     pipe.AddShader(&vs);
12713     pipe.AddShader(&fs);
12714     pipe.AddColorAttachment();
12715     pipe.SetMSAA(&pipe_ms_state_ci);
12716     pipe.SetViewport(m_viewports);
12717     pipe.SetScissor(m_scissors);
12718     pipe.CreateVKPipeline(pipeline_layout, renderPass());
12719
12720     BeginCommandBuffer();
12721     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12722
12723     {
12724         // Create and bind a vertex buffer in a reduced scope, which will cause
12725         // it to be deleted upon leaving this scope
12726         const float vbo_data[3] = {1.f, 0.f, 1.f};
12727         VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data);
12728         draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
12729         draw_verticies.AddVertexInputToPipe(pipe);
12730     }
12731
12732     Draw(1, 0, 0, 0);
12733
12734     EndCommandBuffer();
12735
12736     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
12737     QueueCommandBuffer(false);
12738     m_errorMonitor->VerifyFound();
12739
12740     {
12741         // Create and bind a vertex buffer in a reduced scope, and delete it
12742         // twice, the second through the destructor
12743         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
12744         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message);
12745         buffer_test.TestDoubleDestroy();
12746     }
12747     m_errorMonitor->VerifyFound();
12748
12749     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
12750         // Create and bind a memory buffer with an invalid offset.
12751         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
12752         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
12753         (void)buffer_test;
12754         m_errorMonitor->VerifyFound();
12755     }
12756
12757     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
12758                                             VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
12759         // Create and bind a memory buffer with an invalid offset again,
12760         // but look for a texel buffer message.
12761         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
12762         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12763         (void)buffer_test;
12764         m_errorMonitor->VerifyFound();
12765     }
12766
12767     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
12768         // Create and bind a memory buffer with an invalid offset again, but
12769         // look for a uniform buffer message.
12770         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
12771         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12772         (void)buffer_test;
12773         m_errorMonitor->VerifyFound();
12774     }
12775
12776     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
12777         // Create and bind a memory buffer with an invalid offset again, but
12778         // look for a storage buffer message.
12779         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
12780         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12781         (void)buffer_test;
12782         m_errorMonitor->VerifyFound();
12783     }
12784
12785     {
12786         // Attempt to bind a null buffer.
12787         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message);
12788         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer);
12789         (void)buffer_test;
12790         m_errorMonitor->VerifyFound();
12791     }
12792
12793     {
12794         // Attempt to use an invalid handle to delete a buffer.
12795         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message);
12796         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
12797         (void)buffer_test;
12798     }
12799     m_errorMonitor->VerifyFound();
12800
12801     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12802 }
12803
12804 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
12805 TEST_F(VkLayerTest, InvalidImageLayout) {
12806     TEST_DESCRIPTION("Hit all possible validation checks associated with the "
12807                      "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having"
12808                      "images in the wrong layout when they're copied or transitioned.");
12809     // 3 in ValidateCmdBufImageLayouts
12810     // *  -1 Attempt to submit cmd buf w/ deleted image
12811     // *  -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
12812     // *  -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
12813     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12814                                          "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
12815
12816     ASSERT_NO_FATAL_FAILURE(InitState());
12817     // Create src & dst images to use for copy operations
12818     VkImage src_image;
12819     VkImage dst_image;
12820
12821     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
12822     const int32_t tex_width = 32;
12823     const int32_t tex_height = 32;
12824
12825     VkImageCreateInfo image_create_info = {};
12826     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
12827     image_create_info.pNext = NULL;
12828     image_create_info.imageType = VK_IMAGE_TYPE_2D;
12829     image_create_info.format = tex_format;
12830     image_create_info.extent.width = tex_width;
12831     image_create_info.extent.height = tex_height;
12832     image_create_info.extent.depth = 1;
12833     image_create_info.mipLevels = 1;
12834     image_create_info.arrayLayers = 4;
12835     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
12836     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
12837     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
12838     image_create_info.flags = 0;
12839
12840     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
12841     ASSERT_VK_SUCCESS(err);
12842     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
12843     ASSERT_VK_SUCCESS(err);
12844
12845     BeginCommandBuffer();
12846     VkImageCopy copyRegion;
12847     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12848     copyRegion.srcSubresource.mipLevel = 0;
12849     copyRegion.srcSubresource.baseArrayLayer = 0;
12850     copyRegion.srcSubresource.layerCount = 1;
12851     copyRegion.srcOffset.x = 0;
12852     copyRegion.srcOffset.y = 0;
12853     copyRegion.srcOffset.z = 0;
12854     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12855     copyRegion.dstSubresource.mipLevel = 0;
12856     copyRegion.dstSubresource.baseArrayLayer = 0;
12857     copyRegion.dstSubresource.layerCount = 1;
12858     copyRegion.dstOffset.x = 0;
12859     copyRegion.dstOffset.y = 0;
12860     copyRegion.dstOffset.z = 0;
12861     copyRegion.extent.width = 1;
12862     copyRegion.extent.height = 1;
12863     copyRegion.extent.depth = 1;
12864     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12865     m_errorMonitor->VerifyFound();
12866     // Now cause error due to src image layout changing
12867     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is "
12868                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12869                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12870     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12871     m_errorMonitor->VerifyFound();
12872     // Final src error is due to bad layout type
12873     m_errorMonitor->SetDesiredFailureMsg(
12874         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12875         "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL.");
12876     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12877     m_errorMonitor->VerifyFound();
12878     // Now verify same checks for dst
12879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12880                                          "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
12881     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
12882     m_errorMonitor->VerifyFound();
12883     // Now cause error due to src image layout changing
12884     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is "
12885                                                                         "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12886                                                                         "layout VK_IMAGE_LAYOUT_GENERAL.");
12887     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12888     m_errorMonitor->VerifyFound();
12889     m_errorMonitor->SetDesiredFailureMsg(
12890         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12891         "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL.");
12892     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copyRegion);
12893     m_errorMonitor->VerifyFound();
12894     // Now cause error due to bad image layout transition in PipelineBarrier
12895     VkImageMemoryBarrier image_barrier[1] = {};
12896     image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12897     image_barrier[0].image = src_image;
12898     image_barrier[0].subresourceRange.layerCount = 2;
12899     image_barrier[0].subresourceRange.levelCount = 2;
12900     image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12901     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from "
12902                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when "
12903                                                                         "current layout is VK_IMAGE_LAYOUT_GENERAL.");
12904     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
12905                          NULL, 0, NULL, 1, image_barrier);
12906     m_errorMonitor->VerifyFound();
12907
12908     // Finally some layout errors at RenderPass create time
12909     // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
12910     VkAttachmentReference attach = {};
12911     // perf warning for GENERAL layout w/ non-DS input attachment
12912     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12913     VkSubpassDescription subpass = {};
12914     subpass.inputAttachmentCount = 1;
12915     subpass.pInputAttachments = &attach;
12916     VkRenderPassCreateInfo rpci = {};
12917     rpci.subpassCount = 1;
12918     rpci.pSubpasses = &subpass;
12919     rpci.attachmentCount = 1;
12920     VkAttachmentDescription attach_desc = {};
12921     attach_desc.format = VK_FORMAT_UNDEFINED;
12922     rpci.pAttachments = &attach_desc;
12923     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12924     VkRenderPass rp;
12925     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12926                                          "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
12927     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12928     m_errorMonitor->VerifyFound();
12929     // error w/ non-general layout
12930     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12931
12932     m_errorMonitor->SetDesiredFailureMsg(
12933         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12934         "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
12935     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12936     m_errorMonitor->VerifyFound();
12937     subpass.inputAttachmentCount = 0;
12938     subpass.colorAttachmentCount = 1;
12939     subpass.pColorAttachments = &attach;
12940     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12941     // perf warning for GENERAL layout on color attachment
12942     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12943                                          "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
12944     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12945     m_errorMonitor->VerifyFound();
12946     // error w/ non-color opt or GENERAL layout for color attachment
12947     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12948     m_errorMonitor->SetDesiredFailureMsg(
12949         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12950         "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
12951     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12952     m_errorMonitor->VerifyFound();
12953     subpass.colorAttachmentCount = 0;
12954     subpass.pDepthStencilAttachment = &attach;
12955     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12956     // perf warning for GENERAL layout on DS attachment
12957     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12958                                          "GENERAL layout for depth attachment may not give optimal performance.");
12959     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12960     m_errorMonitor->VerifyFound();
12961     // error w/ non-ds opt or GENERAL layout for color attachment
12962     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12963     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12964                                          "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
12965                                          "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
12966     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12967     m_errorMonitor->VerifyFound();
12968     // For this error we need a valid renderpass so create default one
12969     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12970     attach.attachment = 0;
12971     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
12972     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12973     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
12974     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
12975     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
12976     // Can't do a CLEAR load on READ_ONLY initialLayout
12977     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
12978     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12979     attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout "
12981                                                                         "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_"
12982                                                                         "ONLY_OPTIMAL");
12983     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12984     m_errorMonitor->VerifyFound();
12985
12986     vkDestroyImage(m_device->device(), src_image, NULL);
12987     vkDestroyImage(m_device->device(), dst_image, NULL);
12988 }
12989
12990 TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
12991     TEST_DESCRIPTION("Positive test where we create a renderpass with an "
12992                      "attachment that uses LOAD_OP_CLEAR, the first subpass "
12993                      "has a valid layout, and a second subpass then uses a "
12994                      "valid *READ_ONLY* layout.");
12995     m_errorMonitor->ExpectSuccess();
12996     ASSERT_NO_FATAL_FAILURE(InitState());
12997
12998     VkAttachmentReference attach[2] = {};
12999     attach[0].attachment = 0;
13000     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13001     attach[1].attachment = 0;
13002     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13003     VkSubpassDescription subpasses[2] = {};
13004     // First subpass clears DS attach on load
13005     subpasses[0].pDepthStencilAttachment = &attach[0];
13006     // 2nd subpass reads in DS as input attachment
13007     subpasses[1].inputAttachmentCount = 1;
13008     subpasses[1].pInputAttachments = &attach[1];
13009     VkAttachmentDescription attach_desc = {};
13010     attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
13011     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
13012     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
13013     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
13014     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13015     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13016     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13017     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13018     VkRenderPassCreateInfo rpci = {};
13019     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
13020     rpci.attachmentCount = 1;
13021     rpci.pAttachments = &attach_desc;
13022     rpci.subpassCount = 2;
13023     rpci.pSubpasses = subpasses;
13024
13025     // Now create RenderPass and verify no errors
13026     VkRenderPass rp;
13027     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
13028     m_errorMonitor->VerifyNotFound();
13029
13030     vkDestroyRenderPass(m_device->device(), rp, NULL);
13031 }
13032
13033 TEST_F(VkLayerTest, SimultaneousUse) {
13034     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13035                      "in primary and secondary command buffers.");
13036
13037     ASSERT_NO_FATAL_FAILURE(InitState());
13038     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13039
13040     const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
13041     const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
13042                                             "will cause primary command buffer";
13043
13044     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
13045     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13046     command_buffer_allocate_info.commandPool = m_commandPool;
13047     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13048     command_buffer_allocate_info.commandBufferCount = 1;
13049
13050     VkCommandBuffer secondary_command_buffer;
13051     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
13052     VkCommandBufferBeginInfo command_buffer_begin_info = {};
13053     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
13054     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
13055     command_buffer_inheritance_info.renderPass = m_renderPass;
13056     command_buffer_inheritance_info.framebuffer = m_framebuffer;
13057     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13058     command_buffer_begin_info.flags =
13059         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13060     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
13061
13062     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
13063     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13064     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13065     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13066     vkEndCommandBuffer(secondary_command_buffer);
13067
13068     VkSubmitInfo submit_info = {};
13069     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13070     submit_info.commandBufferCount = 1;
13071     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13072     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13073
13074     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13075     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13076     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1);
13077     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13078     m_errorMonitor->VerifyFound();
13079     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13080     vkEndCommandBuffer(m_commandBuffer->handle());
13081
13082     m_errorMonitor->SetDesiredFailureMsg(0, "");
13083     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13084
13085     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
13086     vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13087     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13088
13089     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2);
13090     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13091     m_errorMonitor->VerifyFound();
13092     vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13093     vkEndCommandBuffer(m_commandBuffer->handle());
13094 }
13095
13096 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
13097     TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13098                      "in primary and secondary command buffers. "
13099                      "Delete objects that are inuse. Call VkQueueSubmit "
13100                      "with an event that has been deleted.");
13101
13102     ASSERT_NO_FATAL_FAILURE(InitState());
13103     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13104
13105     const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x";
13106     const char *cannot_delete_event_message = "Cannot delete event 0x";
13107     const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x";
13108     const char *cannot_destroy_fence_message = "Fence 0x";
13109
13110     BeginCommandBuffer();
13111
13112     VkEvent event;
13113     VkEventCreateInfo event_create_info = {};
13114     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
13115     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13116     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13117
13118     EndCommandBuffer();
13119     vkDestroyEvent(m_device->device(), event, nullptr);
13120
13121     VkSubmitInfo submit_info = {};
13122     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13123     submit_info.commandBufferCount = 1;
13124     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13125     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message);
13126     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13127     m_errorMonitor->VerifyFound();
13128
13129     m_errorMonitor->SetDesiredFailureMsg(0, "");
13130     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13131
13132     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13133
13134     VkSemaphoreCreateInfo semaphore_create_info = {};
13135     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13136     VkSemaphore semaphore;
13137     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13138     VkFenceCreateInfo fence_create_info = {};
13139     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13140     VkFence fence;
13141     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13142
13143     VkDescriptorPoolSize descriptor_pool_type_count = {};
13144     descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13145     descriptor_pool_type_count.descriptorCount = 1;
13146
13147     VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
13148     descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13149     descriptor_pool_create_info.maxSets = 1;
13150     descriptor_pool_create_info.poolSizeCount = 1;
13151     descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
13152     descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
13153
13154     VkDescriptorPool descriptorset_pool;
13155     ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
13156
13157     VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
13158     descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13159     descriptorset_layout_binding.descriptorCount = 1;
13160     descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
13161
13162     VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
13163     descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13164     descriptorset_layout_create_info.bindingCount = 1;
13165     descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
13166
13167     VkDescriptorSetLayout descriptorset_layout;
13168     ASSERT_VK_SUCCESS(
13169         vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
13170
13171     VkDescriptorSet descriptorset;
13172     VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
13173     descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13174     descriptorset_allocate_info.descriptorSetCount = 1;
13175     descriptorset_allocate_info.descriptorPool = descriptorset_pool;
13176     descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
13177     ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
13178
13179     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
13180
13181     VkDescriptorBufferInfo buffer_info = {};
13182     buffer_info.buffer = buffer_test.GetBuffer();
13183     buffer_info.offset = 0;
13184     buffer_info.range = 1024;
13185
13186     VkWriteDescriptorSet write_descriptor_set = {};
13187     write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13188     write_descriptor_set.dstSet = descriptorset;
13189     write_descriptor_set.descriptorCount = 1;
13190     write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13191     write_descriptor_set.pBufferInfo = &buffer_info;
13192
13193     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
13194
13195     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13196     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13197
13198     VkPipelineObj pipe(m_device);
13199     pipe.AddColorAttachment();
13200     pipe.AddShader(&vs);
13201     pipe.AddShader(&fs);
13202
13203     VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
13204     pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13205     pipeline_layout_create_info.setLayoutCount = 1;
13206     pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
13207
13208     VkPipelineLayout pipeline_layout;
13209     ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
13210
13211     pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
13212
13213     BeginCommandBuffer();
13214     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13215
13216     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13217     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13218                             &descriptorset, 0, NULL);
13219
13220     EndCommandBuffer();
13221
13222     submit_info.signalSemaphoreCount = 1;
13223     submit_info.pSignalSemaphores = &semaphore;
13224     vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
13225
13226     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message);
13227     vkDestroyEvent(m_device->device(), event, nullptr);
13228     m_errorMonitor->VerifyFound();
13229
13230     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message);
13231     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13232     m_errorMonitor->VerifyFound();
13233
13234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message);
13235     vkDestroyFence(m_device->device(), fence, nullptr);
13236     m_errorMonitor->VerifyFound();
13237
13238     vkQueueWaitIdle(m_device->m_queue);
13239     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13240     vkDestroyFence(m_device->device(), fence, nullptr);
13241     vkDestroyEvent(m_device->device(), event, nullptr);
13242     vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
13243     vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
13244     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
13245 }
13246
13247 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
13248     TEST_DESCRIPTION("Delete in-use query pool.");
13249
13250     ASSERT_NO_FATAL_FAILURE(InitState());
13251     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13252
13253     VkQueryPool query_pool;
13254     VkQueryPoolCreateInfo query_pool_ci{};
13255     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
13256     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
13257     query_pool_ci.queryCount = 1;
13258     vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13259     BeginCommandBuffer();
13260     // Reset query pool to create binding with cmd buffer
13261     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13262
13263     EndCommandBuffer();
13264
13265     VkSubmitInfo submit_info = {};
13266     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13267     submit_info.commandBufferCount = 1;
13268     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13269     // Submit cmd buffer and then destroy query pool while in-flight
13270     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13271
13272     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x");
13273     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13274     m_errorMonitor->VerifyFound();
13275
13276     vkQueueWaitIdle(m_device->m_queue);
13277     // Now that cmd buffer done we can safely destroy query_pool
13278     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13279 }
13280
13281 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
13282     TEST_DESCRIPTION("Delete in-use pipeline.");
13283
13284     ASSERT_NO_FATAL_FAILURE(InitState());
13285     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13286
13287     // Empty pipeline layout used for binding PSO
13288     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13289     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13290     pipeline_layout_ci.setLayoutCount = 0;
13291     pipeline_layout_ci.pSetLayouts = NULL;
13292
13293     VkPipelineLayout pipeline_layout;
13294     VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout);
13295     ASSERT_VK_SUCCESS(err);
13296
13297     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x");
13298     // Create PSO to be used for draw-time errors below
13299     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13300     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13301     // Store pipeline handle so we can actually delete it before test finishes
13302     VkPipeline delete_this_pipeline;
13303     { // Scope pipeline so it will be auto-deleted
13304         VkPipelineObj pipe(m_device);
13305         pipe.AddShader(&vs);
13306         pipe.AddShader(&fs);
13307         pipe.AddColorAttachment();
13308         pipe.CreateVKPipeline(pipeline_layout, renderPass());
13309         delete_this_pipeline = pipe.handle();
13310
13311         BeginCommandBuffer();
13312         // Bind pipeline to cmd buffer
13313         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13314
13315         EndCommandBuffer();
13316
13317         VkSubmitInfo submit_info = {};
13318         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13319         submit_info.commandBufferCount = 1;
13320         submit_info.pCommandBuffers = &m_commandBuffer->handle();
13321         // Submit cmd buffer and then pipeline destroyed while in-flight
13322         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13323     } // Pipeline deletion triggered here
13324     m_errorMonitor->VerifyFound();
13325     // Make sure queue finished and then actually delete pipeline
13326     vkQueueWaitIdle(m_device->m_queue);
13327     vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
13328     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
13329 }
13330
13331 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
13332     TEST_DESCRIPTION("Delete in-use imageView.");
13333
13334     ASSERT_NO_FATAL_FAILURE(InitState());
13335     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13336
13337     VkDescriptorPoolSize ds_type_count;
13338     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13339     ds_type_count.descriptorCount = 1;
13340
13341     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13342     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13343     ds_pool_ci.maxSets = 1;
13344     ds_pool_ci.poolSizeCount = 1;
13345     ds_pool_ci.pPoolSizes = &ds_type_count;
13346
13347     VkDescriptorPool ds_pool;
13348     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13349     ASSERT_VK_SUCCESS(err);
13350
13351     VkSamplerCreateInfo sampler_ci = {};
13352     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13353     sampler_ci.pNext = NULL;
13354     sampler_ci.magFilter = VK_FILTER_NEAREST;
13355     sampler_ci.minFilter = VK_FILTER_NEAREST;
13356     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13357     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13358     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13359     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13360     sampler_ci.mipLodBias = 1.0;
13361     sampler_ci.anisotropyEnable = VK_FALSE;
13362     sampler_ci.maxAnisotropy = 1;
13363     sampler_ci.compareEnable = VK_FALSE;
13364     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13365     sampler_ci.minLod = 1.0;
13366     sampler_ci.maxLod = 1.0;
13367     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13368     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13369     VkSampler sampler;
13370
13371     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13372     ASSERT_VK_SUCCESS(err);
13373
13374     VkDescriptorSetLayoutBinding layout_binding;
13375     layout_binding.binding = 0;
13376     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13377     layout_binding.descriptorCount = 1;
13378     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13379     layout_binding.pImmutableSamplers = NULL;
13380
13381     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13382     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13383     ds_layout_ci.bindingCount = 1;
13384     ds_layout_ci.pBindings = &layout_binding;
13385     VkDescriptorSetLayout ds_layout;
13386     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13387     ASSERT_VK_SUCCESS(err);
13388
13389     VkDescriptorSetAllocateInfo alloc_info = {};
13390     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13391     alloc_info.descriptorSetCount = 1;
13392     alloc_info.descriptorPool = ds_pool;
13393     alloc_info.pSetLayouts = &ds_layout;
13394     VkDescriptorSet descriptor_set;
13395     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13396     ASSERT_VK_SUCCESS(err);
13397
13398     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13399     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13400     pipeline_layout_ci.pNext = NULL;
13401     pipeline_layout_ci.setLayoutCount = 1;
13402     pipeline_layout_ci.pSetLayouts = &ds_layout;
13403
13404     VkPipelineLayout pipeline_layout;
13405     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13406     ASSERT_VK_SUCCESS(err);
13407
13408     VkImageObj image(m_device);
13409     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13410     ASSERT_TRUE(image.initialized());
13411
13412     VkImageView view;
13413     VkImageViewCreateInfo ivci = {};
13414     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13415     ivci.image = image.handle();
13416     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13417     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13418     ivci.subresourceRange.layerCount = 1;
13419     ivci.subresourceRange.baseMipLevel = 0;
13420     ivci.subresourceRange.levelCount = 1;
13421     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13422
13423     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13424     ASSERT_VK_SUCCESS(err);
13425
13426     VkDescriptorImageInfo image_info{};
13427     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13428     image_info.imageView = view;
13429     image_info.sampler = sampler;
13430
13431     VkWriteDescriptorSet descriptor_write = {};
13432     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13433     descriptor_write.dstSet = descriptor_set;
13434     descriptor_write.dstBinding = 0;
13435     descriptor_write.descriptorCount = 1;
13436     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13437     descriptor_write.pImageInfo = &image_info;
13438
13439     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13440
13441     // Create PSO to use the sampler
13442     char const *vsSource = "#version 450\n"
13443                            "\n"
13444                            "out gl_PerVertex { \n"
13445                            "    vec4 gl_Position;\n"
13446                            "};\n"
13447                            "void main(){\n"
13448                            "   gl_Position = vec4(1);\n"
13449                            "}\n";
13450     char const *fsSource = "#version 450\n"
13451                            "\n"
13452                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13453                            "layout(location=0) out vec4 x;\n"
13454                            "void main(){\n"
13455                            "   x = texture(s, vec2(1));\n"
13456                            "}\n";
13457     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13458     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13459     VkPipelineObj pipe(m_device);
13460     pipe.AddShader(&vs);
13461     pipe.AddShader(&fs);
13462     pipe.AddColorAttachment();
13463     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13464
13465     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
13466
13467     BeginCommandBuffer();
13468     // Bind pipeline to cmd buffer
13469     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13470     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13471                             &descriptor_set, 0, nullptr);
13472     Draw(1, 0, 0, 0);
13473     EndCommandBuffer();
13474     // Submit cmd buffer then destroy sampler
13475     VkSubmitInfo submit_info = {};
13476     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13477     submit_info.commandBufferCount = 1;
13478     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13479     // Submit cmd buffer and then destroy imageView while in-flight
13480     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13481
13482     vkDestroyImageView(m_device->device(), view, nullptr);
13483     m_errorMonitor->VerifyFound();
13484     vkQueueWaitIdle(m_device->m_queue);
13485     // Now we can actually destroy imageView
13486     vkDestroyImageView(m_device->device(), view, NULL);
13487     vkDestroySampler(m_device->device(), sampler, nullptr);
13488     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13489     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13490     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13491 }
13492
13493 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
13494     TEST_DESCRIPTION("Delete in-use bufferView.");
13495
13496     ASSERT_NO_FATAL_FAILURE(InitState());
13497     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13498
13499     VkDescriptorPoolSize ds_type_count;
13500     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13501     ds_type_count.descriptorCount = 1;
13502
13503     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13504     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13505     ds_pool_ci.maxSets = 1;
13506     ds_pool_ci.poolSizeCount = 1;
13507     ds_pool_ci.pPoolSizes = &ds_type_count;
13508
13509     VkDescriptorPool ds_pool;
13510     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13511     ASSERT_VK_SUCCESS(err);
13512
13513     VkDescriptorSetLayoutBinding layout_binding;
13514     layout_binding.binding = 0;
13515     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13516     layout_binding.descriptorCount = 1;
13517     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13518     layout_binding.pImmutableSamplers = NULL;
13519
13520     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13521     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13522     ds_layout_ci.bindingCount = 1;
13523     ds_layout_ci.pBindings = &layout_binding;
13524     VkDescriptorSetLayout ds_layout;
13525     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13526     ASSERT_VK_SUCCESS(err);
13527
13528     VkDescriptorSetAllocateInfo alloc_info = {};
13529     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13530     alloc_info.descriptorSetCount = 1;
13531     alloc_info.descriptorPool = ds_pool;
13532     alloc_info.pSetLayouts = &ds_layout;
13533     VkDescriptorSet descriptor_set;
13534     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13535     ASSERT_VK_SUCCESS(err);
13536
13537     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13538     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13539     pipeline_layout_ci.pNext = NULL;
13540     pipeline_layout_ci.setLayoutCount = 1;
13541     pipeline_layout_ci.pSetLayouts = &ds_layout;
13542
13543     VkPipelineLayout pipeline_layout;
13544     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13545     ASSERT_VK_SUCCESS(err);
13546
13547     VkBuffer buffer;
13548     uint32_t queue_family_index = 0;
13549     VkBufferCreateInfo buffer_create_info = {};
13550     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
13551     buffer_create_info.size = 1024;
13552     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
13553     buffer_create_info.queueFamilyIndexCount = 1;
13554     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
13555
13556     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
13557     ASSERT_VK_SUCCESS(err);
13558
13559     VkMemoryRequirements memory_reqs;
13560     VkDeviceMemory buffer_memory;
13561
13562     VkMemoryAllocateInfo memory_info = {};
13563     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
13564     memory_info.allocationSize = 0;
13565     memory_info.memoryTypeIndex = 0;
13566
13567     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
13568     memory_info.allocationSize = memory_reqs.size;
13569     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
13570     ASSERT_TRUE(pass);
13571
13572     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
13573     ASSERT_VK_SUCCESS(err);
13574     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
13575     ASSERT_VK_SUCCESS(err);
13576
13577     VkBufferView view;
13578     VkBufferViewCreateInfo bvci = {};
13579     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
13580     bvci.buffer = buffer;
13581     bvci.format = VK_FORMAT_R8_UNORM;
13582     bvci.range = VK_WHOLE_SIZE;
13583
13584     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
13585     ASSERT_VK_SUCCESS(err);
13586
13587     VkWriteDescriptorSet descriptor_write = {};
13588     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13589     descriptor_write.dstSet = descriptor_set;
13590     descriptor_write.dstBinding = 0;
13591     descriptor_write.descriptorCount = 1;
13592     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13593     descriptor_write.pTexelBufferView = &view;
13594
13595     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13596
13597     char const *vsSource = "#version 450\n"
13598                            "\n"
13599                            "out gl_PerVertex { \n"
13600                            "    vec4 gl_Position;\n"
13601                            "};\n"
13602                            "void main(){\n"
13603                            "   gl_Position = vec4(1);\n"
13604                            "}\n";
13605     char const *fsSource = "#version 450\n"
13606                            "\n"
13607                            "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
13608                            "layout(location=0) out vec4 x;\n"
13609                            "void main(){\n"
13610                            "   x = imageLoad(s, 0);\n"
13611                            "}\n";
13612     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13613     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13614     VkPipelineObj pipe(m_device);
13615     pipe.AddShader(&vs);
13616     pipe.AddShader(&fs);
13617     pipe.AddColorAttachment();
13618     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13619
13620     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
13621
13622     BeginCommandBuffer();
13623     VkViewport viewport = {0, 0, 16, 16, 0, 1};
13624     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
13625     VkRect2D scissor = {{0, 0}, {16, 16}};
13626     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
13627     // Bind pipeline to cmd buffer
13628     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13629     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13630                             &descriptor_set, 0, nullptr);
13631     Draw(1, 0, 0, 0);
13632     EndCommandBuffer();
13633
13634     VkSubmitInfo submit_info = {};
13635     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13636     submit_info.commandBufferCount = 1;
13637     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13638     // Submit cmd buffer and then destroy bufferView while in-flight
13639     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13640
13641     vkDestroyBufferView(m_device->device(), view, nullptr);
13642     m_errorMonitor->VerifyFound();
13643     vkQueueWaitIdle(m_device->m_queue);
13644     // Now we can actually destroy bufferView
13645     vkDestroyBufferView(m_device->device(), view, NULL);
13646     vkDestroyBuffer(m_device->device(), buffer, NULL);
13647     vkFreeMemory(m_device->device(), buffer_memory, NULL);
13648     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13649     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13650     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13651 }
13652
13653 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
13654     TEST_DESCRIPTION("Delete in-use sampler.");
13655
13656     ASSERT_NO_FATAL_FAILURE(InitState());
13657     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13658
13659     VkDescriptorPoolSize ds_type_count;
13660     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13661     ds_type_count.descriptorCount = 1;
13662
13663     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13664     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13665     ds_pool_ci.maxSets = 1;
13666     ds_pool_ci.poolSizeCount = 1;
13667     ds_pool_ci.pPoolSizes = &ds_type_count;
13668
13669     VkDescriptorPool ds_pool;
13670     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13671     ASSERT_VK_SUCCESS(err);
13672
13673     VkSamplerCreateInfo sampler_ci = {};
13674     sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13675     sampler_ci.pNext = NULL;
13676     sampler_ci.magFilter = VK_FILTER_NEAREST;
13677     sampler_ci.minFilter = VK_FILTER_NEAREST;
13678     sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13679     sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13680     sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13681     sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13682     sampler_ci.mipLodBias = 1.0;
13683     sampler_ci.anisotropyEnable = VK_FALSE;
13684     sampler_ci.maxAnisotropy = 1;
13685     sampler_ci.compareEnable = VK_FALSE;
13686     sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13687     sampler_ci.minLod = 1.0;
13688     sampler_ci.maxLod = 1.0;
13689     sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13690     sampler_ci.unnormalizedCoordinates = VK_FALSE;
13691     VkSampler sampler;
13692
13693     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13694     ASSERT_VK_SUCCESS(err);
13695
13696     VkDescriptorSetLayoutBinding layout_binding;
13697     layout_binding.binding = 0;
13698     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13699     layout_binding.descriptorCount = 1;
13700     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13701     layout_binding.pImmutableSamplers = NULL;
13702
13703     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13704     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13705     ds_layout_ci.bindingCount = 1;
13706     ds_layout_ci.pBindings = &layout_binding;
13707     VkDescriptorSetLayout ds_layout;
13708     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13709     ASSERT_VK_SUCCESS(err);
13710
13711     VkDescriptorSetAllocateInfo alloc_info = {};
13712     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13713     alloc_info.descriptorSetCount = 1;
13714     alloc_info.descriptorPool = ds_pool;
13715     alloc_info.pSetLayouts = &ds_layout;
13716     VkDescriptorSet descriptor_set;
13717     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13718     ASSERT_VK_SUCCESS(err);
13719
13720     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13721     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13722     pipeline_layout_ci.pNext = NULL;
13723     pipeline_layout_ci.setLayoutCount = 1;
13724     pipeline_layout_ci.pSetLayouts = &ds_layout;
13725
13726     VkPipelineLayout pipeline_layout;
13727     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13728     ASSERT_VK_SUCCESS(err);
13729
13730     VkImageObj image(m_device);
13731     image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13732     ASSERT_TRUE(image.initialized());
13733
13734     VkImageView view;
13735     VkImageViewCreateInfo ivci = {};
13736     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13737     ivci.image = image.handle();
13738     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13739     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13740     ivci.subresourceRange.layerCount = 1;
13741     ivci.subresourceRange.baseMipLevel = 0;
13742     ivci.subresourceRange.levelCount = 1;
13743     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13744
13745     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13746     ASSERT_VK_SUCCESS(err);
13747
13748     VkDescriptorImageInfo image_info{};
13749     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13750     image_info.imageView = view;
13751     image_info.sampler = sampler;
13752
13753     VkWriteDescriptorSet descriptor_write = {};
13754     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13755     descriptor_write.dstSet = descriptor_set;
13756     descriptor_write.dstBinding = 0;
13757     descriptor_write.descriptorCount = 1;
13758     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13759     descriptor_write.pImageInfo = &image_info;
13760
13761     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13762
13763     // Create PSO to use the sampler
13764     char const *vsSource = "#version 450\n"
13765                            "\n"
13766                            "out gl_PerVertex { \n"
13767                            "    vec4 gl_Position;\n"
13768                            "};\n"
13769                            "void main(){\n"
13770                            "   gl_Position = vec4(1);\n"
13771                            "}\n";
13772     char const *fsSource = "#version 450\n"
13773                            "\n"
13774                            "layout(set=0, binding=0) uniform sampler2D s;\n"
13775                            "layout(location=0) out vec4 x;\n"
13776                            "void main(){\n"
13777                            "   x = texture(s, vec2(1));\n"
13778                            "}\n";
13779     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13780     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13781     VkPipelineObj pipe(m_device);
13782     pipe.AddShader(&vs);
13783     pipe.AddShader(&fs);
13784     pipe.AddColorAttachment();
13785     pipe.CreateVKPipeline(pipeline_layout, renderPass());
13786
13787     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x");
13788
13789     BeginCommandBuffer();
13790     // Bind pipeline to cmd buffer
13791     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13792     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13793                             &descriptor_set, 0, nullptr);
13794     Draw(1, 0, 0, 0);
13795     EndCommandBuffer();
13796     // Submit cmd buffer then destroy sampler
13797     VkSubmitInfo submit_info = {};
13798     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13799     submit_info.commandBufferCount = 1;
13800     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13801     // Submit cmd buffer and then destroy sampler while in-flight
13802     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13803
13804     vkDestroySampler(m_device->device(), sampler, nullptr);
13805     m_errorMonitor->VerifyFound();
13806     vkQueueWaitIdle(m_device->m_queue);
13807     // Now we can actually destroy sampler
13808     vkDestroySampler(m_device->device(), sampler, nullptr);
13809     vkDestroyImageView(m_device->device(), view, NULL);
13810     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13811     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13812     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13813 }
13814
13815 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
13816     TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already "
13817                      "signaled but not waited on by the queue. Wait on a "
13818                      "fence that has not yet been submitted to a queue.");
13819
13820     ASSERT_NO_FATAL_FAILURE(InitState());
13821     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13822
13823     const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
13824     const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during "
13825                                              "acquire next image.";
13826
13827     BeginCommandBuffer();
13828     EndCommandBuffer();
13829
13830     VkSemaphoreCreateInfo semaphore_create_info = {};
13831     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13832     VkSemaphore semaphore;
13833     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13834     VkSubmitInfo submit_info = {};
13835     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13836     submit_info.commandBufferCount = 1;
13837     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13838     submit_info.signalSemaphoreCount = 1;
13839     submit_info.pSignalSemaphores = &semaphore;
13840     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13841     m_errorMonitor->SetDesiredFailureMsg(0, "");
13842     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13843     BeginCommandBuffer();
13844     EndCommandBuffer();
13845     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
13846     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13847     m_errorMonitor->VerifyFound();
13848
13849     VkFenceCreateInfo fence_create_info = {};
13850     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13851     VkFence fence;
13852     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13853
13854     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
13855     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
13856     m_errorMonitor->VerifyFound();
13857
13858     vkDeviceWaitIdle(m_device->device());
13859     vkDestroyFence(m_device->device(), fence, nullptr);
13860     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13861 }
13862
13863 TEST_F(VkLayerTest, FramebufferIncompatible) {
13864     TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
13865                      "that does not match the framebuffer for the active "
13866                      "renderpass.");
13867     ASSERT_NO_FATAL_FAILURE(InitState());
13868     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13869
13870     // A renderpass with one color attachment.
13871     VkAttachmentDescription attachment = {0,
13872                                           VK_FORMAT_B8G8R8A8_UNORM,
13873                                           VK_SAMPLE_COUNT_1_BIT,
13874                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13875                                           VK_ATTACHMENT_STORE_OP_STORE,
13876                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13877                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
13878                                           VK_IMAGE_LAYOUT_UNDEFINED,
13879                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13880
13881     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13882
13883     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
13884
13885     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
13886
13887     VkRenderPass rp;
13888     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
13889     ASSERT_VK_SUCCESS(err);
13890
13891     // A compatible framebuffer.
13892     VkImageObj image(m_device);
13893     image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13894     ASSERT_TRUE(image.initialized());
13895
13896     VkImageViewCreateInfo ivci = {
13897         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
13898         nullptr,
13899         0,
13900         image.handle(),
13901         VK_IMAGE_VIEW_TYPE_2D,
13902         VK_FORMAT_B8G8R8A8_UNORM,
13903         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13904          VK_COMPONENT_SWIZZLE_IDENTITY},
13905         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
13906     };
13907     VkImageView view;
13908     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
13909     ASSERT_VK_SUCCESS(err);
13910
13911     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
13912     VkFramebuffer fb;
13913     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
13914     ASSERT_VK_SUCCESS(err);
13915
13916     VkCommandBufferAllocateInfo cbai = {};
13917     cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13918     cbai.commandPool = m_commandPool;
13919     cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13920     cbai.commandBufferCount = 1;
13921
13922     VkCommandBuffer sec_cb;
13923     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
13924     ASSERT_VK_SUCCESS(err);
13925     VkCommandBufferBeginInfo cbbi = {};
13926     VkCommandBufferInheritanceInfo cbii = {};
13927     cbii.renderPass = renderPass();
13928     cbii.framebuffer = fb;
13929     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13930     cbbi.pNext = NULL;
13931     cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13932     cbbi.pInheritanceInfo = &cbii;
13933     vkBeginCommandBuffer(sec_cb, &cbbi);
13934     vkEndCommandBuffer(sec_cb);
13935
13936     VkCommandBufferBeginInfo cbbi2 = {
13937         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
13938         0, nullptr
13939     };
13940     vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
13941     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13942
13943     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13944                                          " that is not the same as the primaryCB's current active framebuffer ");
13945     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
13946     m_errorMonitor->VerifyFound();
13947     // Cleanup
13948     vkDestroyImageView(m_device->device(), view, NULL);
13949     vkDestroyRenderPass(m_device->device(), rp, NULL);
13950     vkDestroyFramebuffer(m_device->device(), fb, NULL);
13951 }
13952
13953 TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
13954     TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
13955                      "invalid value. If logicOp is not available, attempt to "
13956                      "use it and verify that we see the correct error.");
13957     ASSERT_NO_FATAL_FAILURE(InitState());
13958     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13959
13960     auto features = m_device->phy().features();
13961     // Set the expected error depending on whether or not logicOp available
13962     if (VK_FALSE == features.logicOp) {
13963         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not "
13964                                                                             "enabled, logicOpEnable must be "
13965                                                                             "VK_FALSE");
13966     } else {
13967         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
13968     }
13969     // Create a pipeline using logicOp
13970     VkResult err;
13971
13972     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13973     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13974
13975     VkPipelineLayout pipeline_layout;
13976     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13977     ASSERT_VK_SUCCESS(err);
13978
13979     VkPipelineViewportStateCreateInfo vp_state_ci = {};
13980     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13981     vp_state_ci.viewportCount = 1;
13982     VkViewport vp = {}; // Just need dummy vp to point to
13983     vp_state_ci.pViewports = &vp;
13984     vp_state_ci.scissorCount = 1;
13985     VkRect2D scissors = {}; // Dummy scissors to point to
13986     vp_state_ci.pScissors = &scissors;
13987
13988     VkPipelineShaderStageCreateInfo shaderStages[2];
13989     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
13990
13991     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13992     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13993     shaderStages[0] = vs.GetStageCreateInfo();
13994     shaderStages[1] = fs.GetStageCreateInfo();
13995
13996     VkPipelineVertexInputStateCreateInfo vi_ci = {};
13997     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13998
13999     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
14000     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
14001     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
14002
14003     VkPipelineRasterizationStateCreateInfo rs_ci = {};
14004     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14005     rs_ci.lineWidth = 1.0f;
14006
14007     VkPipelineColorBlendAttachmentState att = {};
14008     att.blendEnable = VK_FALSE;
14009     att.colorWriteMask = 0xf;
14010
14011     VkPipelineColorBlendStateCreateInfo cb_ci = {};
14012     cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
14013     // Enable logicOp & set logicOp to value 1 beyond allowed entries
14014     cb_ci.logicOpEnable = VK_TRUE;
14015     cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
14016     cb_ci.attachmentCount = 1;
14017     cb_ci.pAttachments = &att;
14018
14019     VkPipelineMultisampleStateCreateInfo ms_ci = {};
14020     ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14021     ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14022
14023     VkGraphicsPipelineCreateInfo gp_ci = {};
14024     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14025     gp_ci.stageCount = 2;
14026     gp_ci.pStages = shaderStages;
14027     gp_ci.pVertexInputState = &vi_ci;
14028     gp_ci.pInputAssemblyState = &ia_ci;
14029     gp_ci.pViewportState = &vp_state_ci;
14030     gp_ci.pRasterizationState = &rs_ci;
14031     gp_ci.pColorBlendState = &cb_ci;
14032     gp_ci.pMultisampleState = &ms_ci;
14033     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14034     gp_ci.layout = pipeline_layout;
14035     gp_ci.renderPass = renderPass();
14036
14037     VkPipelineCacheCreateInfo pc_ci = {};
14038     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14039
14040     VkPipeline pipeline;
14041     VkPipelineCache pipelineCache;
14042     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
14043     ASSERT_VK_SUCCESS(err);
14044
14045     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
14046     m_errorMonitor->VerifyFound();
14047     if (VK_SUCCESS == err) {
14048         vkDestroyPipeline(m_device->device(), pipeline, NULL);
14049     }
14050     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
14051     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
14052 }
14053 #endif // DRAW_STATE_TESTS
14054
14055 #if THREADING_TESTS
14056 #if GTEST_IS_THREADSAFE
14057 struct thread_data_struct {
14058     VkCommandBuffer commandBuffer;
14059     VkEvent event;
14060     bool bailout;
14061 };
14062
14063 extern "C" void *AddToCommandBuffer(void *arg) {
14064     struct thread_data_struct *data = (struct thread_data_struct *)arg;
14065
14066     for (int i = 0; i < 80000; i++) {
14067         vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
14068         if (data->bailout) {
14069             break;
14070         }
14071     }
14072     return NULL;
14073 }
14074
14075 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
14076     test_platform_thread thread;
14077
14078     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
14079
14080     ASSERT_NO_FATAL_FAILURE(InitState());
14081     ASSERT_NO_FATAL_FAILURE(InitViewport());
14082     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14083
14084     // Calls AllocateCommandBuffers
14085     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
14086
14087     // Avoid creating RenderPass
14088     commandBuffer.BeginCommandBuffer();
14089
14090     VkEventCreateInfo event_info;
14091     VkEvent event;
14092     VkResult err;
14093
14094     memset(&event_info, 0, sizeof(event_info));
14095     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
14096
14097     err = vkCreateEvent(device(), &event_info, NULL, &event);
14098     ASSERT_VK_SUCCESS(err);
14099
14100     err = vkResetEvent(device(), event);
14101     ASSERT_VK_SUCCESS(err);
14102
14103     struct thread_data_struct data;
14104     data.commandBuffer = commandBuffer.GetBufferHandle();
14105     data.event = event;
14106     data.bailout = false;
14107     m_errorMonitor->SetBailout(&data.bailout);
14108
14109     // First do some correct operations using multiple threads.
14110     // Add many entries to command buffer from another thread.
14111     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14112     // Make non-conflicting calls from this thread at the same time.
14113     for (int i = 0; i < 80000; i++) {
14114         uint32_t count;
14115         vkEnumeratePhysicalDevices(instance(), &count, NULL);
14116     }
14117     test_platform_thread_join(thread, NULL);
14118
14119     // Then do some incorrect operations using multiple threads.
14120     // Add many entries to command buffer from another thread.
14121     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14122     // Add many entries to command buffer from this thread at the same time.
14123     AddToCommandBuffer(&data);
14124
14125     test_platform_thread_join(thread, NULL);
14126     commandBuffer.EndCommandBuffer();
14127
14128     m_errorMonitor->SetBailout(NULL);
14129
14130     m_errorMonitor->VerifyFound();
14131
14132     vkDestroyEvent(device(), event, NULL);
14133 }
14134 #endif // GTEST_IS_THREADSAFE
14135 #endif // THREADING_TESTS
14136
14137 #if SHADER_CHECKER_TESTS
14138 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
14139     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14140                      "with an impossible code size");
14141
14142     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
14143
14144     ASSERT_NO_FATAL_FAILURE(InitState());
14145     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14146
14147     VkShaderModule module;
14148     VkShaderModuleCreateInfo moduleCreateInfo;
14149     struct icd_spv_header spv;
14150
14151     spv.magic = ICD_SPV_MAGIC;
14152     spv.version = ICD_SPV_VERSION;
14153     spv.gen_magic = 0;
14154
14155     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14156     moduleCreateInfo.pNext = NULL;
14157     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14158     moduleCreateInfo.codeSize = 4;
14159     moduleCreateInfo.flags = 0;
14160     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14161
14162     m_errorMonitor->VerifyFound();
14163 }
14164
14165 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
14166     TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14167                      "with a bad magic number");
14168
14169     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
14170
14171     ASSERT_NO_FATAL_FAILURE(InitState());
14172     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14173
14174     VkShaderModule module;
14175     VkShaderModuleCreateInfo moduleCreateInfo;
14176     struct icd_spv_header spv;
14177
14178     spv.magic = ~ICD_SPV_MAGIC;
14179     spv.version = ICD_SPV_VERSION;
14180     spv.gen_magic = 0;
14181
14182     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14183     moduleCreateInfo.pNext = NULL;
14184     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14185     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14186     moduleCreateInfo.flags = 0;
14187     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14188
14189     m_errorMonitor->VerifyFound();
14190 }
14191
14192 #if 0
14193 // Not currently covered by SPIRV-Tools validator
14194 TEST_F(VkLayerTest, InvalidSPIRVVersion) {
14195     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14196                                          "Invalid SPIR-V header");
14197
14198     ASSERT_NO_FATAL_FAILURE(InitState());
14199     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14200
14201     VkShaderModule module;
14202     VkShaderModuleCreateInfo moduleCreateInfo;
14203     struct icd_spv_header spv;
14204
14205     spv.magic = ICD_SPV_MAGIC;
14206     spv.version = ~ICD_SPV_VERSION;
14207     spv.gen_magic = 0;
14208
14209     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14210     moduleCreateInfo.pNext = NULL;
14211
14212     moduleCreateInfo.pCode = (const uint32_t *)&spv;
14213     moduleCreateInfo.codeSize = sizeof(spv) + 10;
14214     moduleCreateInfo.flags = 0;
14215     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14216
14217     m_errorMonitor->VerifyFound();
14218 }
14219 #endif
14220
14221 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
14222     TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
14223                      "is not consumed by the fragment stage");
14224     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
14225
14226     ASSERT_NO_FATAL_FAILURE(InitState());
14227     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14228
14229     char const *vsSource = "#version 450\n"
14230                            "\n"
14231                            "layout(location=0) out float x;\n"
14232                            "out gl_PerVertex {\n"
14233                            "    vec4 gl_Position;\n"
14234                            "};\n"
14235                            "void main(){\n"
14236                            "   gl_Position = vec4(1);\n"
14237                            "   x = 0;\n"
14238                            "}\n";
14239     char const *fsSource = "#version 450\n"
14240                            "\n"
14241                            "layout(location=0) out vec4 color;\n"
14242                            "void main(){\n"
14243                            "   color = vec4(1);\n"
14244                            "}\n";
14245
14246     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14247     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14248
14249     VkPipelineObj pipe(m_device);
14250     pipe.AddColorAttachment();
14251     pipe.AddShader(&vs);
14252     pipe.AddShader(&fs);
14253
14254     VkDescriptorSetObj descriptorSet(m_device);
14255     descriptorSet.AppendDummy();
14256     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14257
14258     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14259
14260     m_errorMonitor->VerifyFound();
14261 }
14262
14263 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
14264     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14265                      "which is not present in the outputs of the previous stage");
14266
14267     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14268
14269     ASSERT_NO_FATAL_FAILURE(InitState());
14270     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14271
14272     char const *vsSource = "#version 450\n"
14273                            "\n"
14274                            "out gl_PerVertex {\n"
14275                            "    vec4 gl_Position;\n"
14276                            "};\n"
14277                            "void main(){\n"
14278                            "   gl_Position = vec4(1);\n"
14279                            "}\n";
14280     char const *fsSource = "#version 450\n"
14281                            "\n"
14282                            "layout(location=0) in float x;\n"
14283                            "layout(location=0) out vec4 color;\n"
14284                            "void main(){\n"
14285                            "   color = vec4(x);\n"
14286                            "}\n";
14287
14288     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14289     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14290
14291     VkPipelineObj pipe(m_device);
14292     pipe.AddColorAttachment();
14293     pipe.AddShader(&vs);
14294     pipe.AddShader(&fs);
14295
14296     VkDescriptorSetObj descriptorSet(m_device);
14297     descriptorSet.AppendDummy();
14298     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14299
14300     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14301
14302     m_errorMonitor->VerifyFound();
14303 }
14304
14305 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
14306     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14307                      "within an interace block, which is not present in the outputs "
14308                      "of the previous stage.");
14309     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14310
14311     ASSERT_NO_FATAL_FAILURE(InitState());
14312     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14313
14314     char const *vsSource = "#version 450\n"
14315                            "\n"
14316                            "out gl_PerVertex {\n"
14317                            "    vec4 gl_Position;\n"
14318                            "};\n"
14319                            "void main(){\n"
14320                            "   gl_Position = vec4(1);\n"
14321                            "}\n";
14322     char const *fsSource = "#version 450\n"
14323                            "\n"
14324                            "in block { layout(location=0) float x; } ins;\n"
14325                            "layout(location=0) out vec4 color;\n"
14326                            "void main(){\n"
14327                            "   color = vec4(ins.x);\n"
14328                            "}\n";
14329
14330     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14331     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14332
14333     VkPipelineObj pipe(m_device);
14334     pipe.AddColorAttachment();
14335     pipe.AddShader(&vs);
14336     pipe.AddShader(&fs);
14337
14338     VkDescriptorSetObj descriptorSet(m_device);
14339     descriptorSet.AppendDummy();
14340     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14341
14342     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14343
14344     m_errorMonitor->VerifyFound();
14345 }
14346
14347 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
14348     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
14349                      "across the VS->FS interface");
14350     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
14351                                                                         "output arr[2] of float32' vs 'ptr to "
14352                                                                         "input arr[3] of float32'");
14353
14354     ASSERT_NO_FATAL_FAILURE(InitState());
14355     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14356
14357     char const *vsSource = "#version 450\n"
14358                            "\n"
14359                            "layout(location=0) out float x[2];\n"
14360                            "out gl_PerVertex {\n"
14361                            "    vec4 gl_Position;\n"
14362                            "};\n"
14363                            "void main(){\n"
14364                            "   x[0] = 0; x[1] = 0;\n"
14365                            "   gl_Position = vec4(1);\n"
14366                            "}\n";
14367     char const *fsSource = "#version 450\n"
14368                            "\n"
14369                            "layout(location=0) in float x[3];\n"
14370                            "layout(location=0) out vec4 color;\n"
14371                            "void main(){\n"
14372                            "   color = vec4(x[0] + x[1] + x[2]);\n"
14373                            "}\n";
14374
14375     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14376     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14377
14378     VkPipelineObj pipe(m_device);
14379     pipe.AddColorAttachment();
14380     pipe.AddShader(&vs);
14381     pipe.AddShader(&fs);
14382
14383     VkDescriptorSetObj descriptorSet(m_device);
14384     descriptorSet.AppendDummy();
14385     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14386
14387     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14388
14389     m_errorMonitor->VerifyFound();
14390 }
14391
14392 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
14393     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14394                      "the VS->FS interface");
14395     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14396
14397     ASSERT_NO_FATAL_FAILURE(InitState());
14398     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14399
14400     char const *vsSource = "#version 450\n"
14401                            "\n"
14402                            "layout(location=0) out int x;\n"
14403                            "out gl_PerVertex {\n"
14404                            "    vec4 gl_Position;\n"
14405                            "};\n"
14406                            "void main(){\n"
14407                            "   x = 0;\n"
14408                            "   gl_Position = vec4(1);\n"
14409                            "}\n";
14410     char const *fsSource = "#version 450\n"
14411                            "\n"
14412                            "layout(location=0) in float x;\n" /* VS writes int */
14413                            "layout(location=0) out vec4 color;\n"
14414                            "void main(){\n"
14415                            "   color = vec4(x);\n"
14416                            "}\n";
14417
14418     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14419     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14420
14421     VkPipelineObj pipe(m_device);
14422     pipe.AddColorAttachment();
14423     pipe.AddShader(&vs);
14424     pipe.AddShader(&fs);
14425
14426     VkDescriptorSetObj descriptorSet(m_device);
14427     descriptorSet.AppendDummy();
14428     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14429
14430     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14431
14432     m_errorMonitor->VerifyFound();
14433 }
14434
14435 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
14436     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14437                      "the VS->FS interface, when the variable is contained within "
14438                      "an interface block");
14439     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14440
14441     ASSERT_NO_FATAL_FAILURE(InitState());
14442     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14443
14444     char const *vsSource = "#version 450\n"
14445                            "\n"
14446                            "out block { layout(location=0) int x; } outs;\n"
14447                            "out gl_PerVertex {\n"
14448                            "    vec4 gl_Position;\n"
14449                            "};\n"
14450                            "void main(){\n"
14451                            "   outs.x = 0;\n"
14452                            "   gl_Position = vec4(1);\n"
14453                            "}\n";
14454     char const *fsSource = "#version 450\n"
14455                            "\n"
14456                            "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
14457                            "layout(location=0) out vec4 color;\n"
14458                            "void main(){\n"
14459                            "   color = vec4(ins.x);\n"
14460                            "}\n";
14461
14462     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14463     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14464
14465     VkPipelineObj pipe(m_device);
14466     pipe.AddColorAttachment();
14467     pipe.AddShader(&vs);
14468     pipe.AddShader(&fs);
14469
14470     VkDescriptorSetObj descriptorSet(m_device);
14471     descriptorSet.AppendDummy();
14472     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14473
14474     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14475
14476     m_errorMonitor->VerifyFound();
14477 }
14478
14479 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
14480     TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
14481                      "the VS->FS interface; This should manifest as a not-written/not-consumed "
14482                      "pair, but flushes out broken walking of the interfaces");
14483     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
14484
14485     ASSERT_NO_FATAL_FAILURE(InitState());
14486     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14487
14488     char const *vsSource = "#version 450\n"
14489                            "\n"
14490                            "out block { layout(location=1) float x; } outs;\n"
14491                            "out gl_PerVertex {\n"
14492                            "    vec4 gl_Position;\n"
14493                            "};\n"
14494                            "void main(){\n"
14495                            "   outs.x = 0;\n"
14496                            "   gl_Position = vec4(1);\n"
14497                            "}\n";
14498     char const *fsSource = "#version 450\n"
14499                            "\n"
14500                            "in block { layout(location=0) float x; } ins;\n"
14501                            "layout(location=0) out vec4 color;\n"
14502                            "void main(){\n"
14503                            "   color = vec4(ins.x);\n"
14504                            "}\n";
14505
14506     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14507     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14508
14509     VkPipelineObj pipe(m_device);
14510     pipe.AddColorAttachment();
14511     pipe.AddShader(&vs);
14512     pipe.AddShader(&fs);
14513
14514     VkDescriptorSetObj descriptorSet(m_device);
14515     descriptorSet.AppendDummy();
14516     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14517
14518     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14519
14520     m_errorMonitor->VerifyFound();
14521 }
14522
14523 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
14524     TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
14525                      "VS->FS interface. It's not enough to have the same set of locations in "
14526                      "use; matching is defined in terms of spirv variables.");
14527     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
14528
14529     ASSERT_NO_FATAL_FAILURE(InitState());
14530     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14531
14532     char const *vsSource = "#version 450\n"
14533                            "\n"
14534                            "out block { layout(location=0, component=0) float x; } outs;\n"
14535                            "out gl_PerVertex {\n"
14536                            "    vec4 gl_Position;\n"
14537                            "};\n"
14538                            "void main(){\n"
14539                            "   outs.x = 0;\n"
14540                            "   gl_Position = vec4(1);\n"
14541                            "}\n";
14542     char const *fsSource = "#version 450\n"
14543                            "\n"
14544                            "in block { layout(location=0, component=1) float x; } ins;\n"
14545                            "layout(location=0) out vec4 color;\n"
14546                            "void main(){\n"
14547                            "   color = vec4(ins.x);\n"
14548                            "}\n";
14549
14550     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14551     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14552
14553     VkPipelineObj pipe(m_device);
14554     pipe.AddColorAttachment();
14555     pipe.AddShader(&vs);
14556     pipe.AddShader(&fs);
14557
14558     VkDescriptorSetObj descriptorSet(m_device);
14559     descriptorSet.AppendDummy();
14560     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14561
14562     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14563
14564     m_errorMonitor->VerifyFound();
14565 }
14566
14567 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
14568     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
14569                      "not consumed by the vertex shader");
14570     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14571
14572     ASSERT_NO_FATAL_FAILURE(InitState());
14573     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14574
14575     VkVertexInputBindingDescription input_binding;
14576     memset(&input_binding, 0, sizeof(input_binding));
14577
14578     VkVertexInputAttributeDescription input_attrib;
14579     memset(&input_attrib, 0, sizeof(input_attrib));
14580     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14581
14582     char const *vsSource = "#version 450\n"
14583                            "\n"
14584                            "out gl_PerVertex {\n"
14585                            "    vec4 gl_Position;\n"
14586                            "};\n"
14587                            "void main(){\n"
14588                            "   gl_Position = vec4(1);\n"
14589                            "}\n";
14590     char const *fsSource = "#version 450\n"
14591                            "\n"
14592                            "layout(location=0) out vec4 color;\n"
14593                            "void main(){\n"
14594                            "   color = vec4(1);\n"
14595                            "}\n";
14596
14597     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14598     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14599
14600     VkPipelineObj pipe(m_device);
14601     pipe.AddColorAttachment();
14602     pipe.AddShader(&vs);
14603     pipe.AddShader(&fs);
14604
14605     pipe.AddVertexInputBindings(&input_binding, 1);
14606     pipe.AddVertexInputAttribs(&input_attrib, 1);
14607
14608     VkDescriptorSetObj descriptorSet(m_device);
14609     descriptorSet.AppendDummy();
14610     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14611
14612     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14613
14614     m_errorMonitor->VerifyFound();
14615 }
14616
14617 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
14618     TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
14619                      "vertex attributes. This flushes out bad behavior in the interface walker");
14620     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14621
14622     ASSERT_NO_FATAL_FAILURE(InitState());
14623     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14624
14625     VkVertexInputBindingDescription input_binding;
14626     memset(&input_binding, 0, sizeof(input_binding));
14627
14628     VkVertexInputAttributeDescription input_attrib;
14629     memset(&input_attrib, 0, sizeof(input_attrib));
14630     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14631
14632     char const *vsSource = "#version 450\n"
14633                            "\n"
14634                            "layout(location=1) in float x;\n"
14635                            "out gl_PerVertex {\n"
14636                            "    vec4 gl_Position;\n"
14637                            "};\n"
14638                            "void main(){\n"
14639                            "   gl_Position = vec4(x);\n"
14640                            "}\n";
14641     char const *fsSource = "#version 450\n"
14642                            "\n"
14643                            "layout(location=0) out vec4 color;\n"
14644                            "void main(){\n"
14645                            "   color = vec4(1);\n"
14646                            "}\n";
14647
14648     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14649     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14650
14651     VkPipelineObj pipe(m_device);
14652     pipe.AddColorAttachment();
14653     pipe.AddShader(&vs);
14654     pipe.AddShader(&fs);
14655
14656     pipe.AddVertexInputBindings(&input_binding, 1);
14657     pipe.AddVertexInputAttribs(&input_attrib, 1);
14658
14659     VkDescriptorSetObj descriptorSet(m_device);
14660     descriptorSet.AppendDummy();
14661     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14662
14663     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14664
14665     m_errorMonitor->VerifyFound();
14666 }
14667
14668 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
14669     TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
14670                      "provided by a vertex attribute");
14671     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
14672
14673     ASSERT_NO_FATAL_FAILURE(InitState());
14674     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14675
14676     char const *vsSource = "#version 450\n"
14677                            "\n"
14678                            "layout(location=0) in vec4 x;\n" /* not provided */
14679                            "out gl_PerVertex {\n"
14680                            "    vec4 gl_Position;\n"
14681                            "};\n"
14682                            "void main(){\n"
14683                            "   gl_Position = x;\n"
14684                            "}\n";
14685     char const *fsSource = "#version 450\n"
14686                            "\n"
14687                            "layout(location=0) out vec4 color;\n"
14688                            "void main(){\n"
14689                            "   color = vec4(1);\n"
14690                            "}\n";
14691
14692     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14693     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14694
14695     VkPipelineObj pipe(m_device);
14696     pipe.AddColorAttachment();
14697     pipe.AddShader(&vs);
14698     pipe.AddShader(&fs);
14699
14700     VkDescriptorSetObj descriptorSet(m_device);
14701     descriptorSet.AppendDummy();
14702     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14703
14704     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14705
14706     m_errorMonitor->VerifyFound();
14707 }
14708
14709 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
14710     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
14711                      "fundamental type (float/int/uint) of an attribute and the "
14712                      "vertex shader input that consumes it");
14713     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
14714
14715     ASSERT_NO_FATAL_FAILURE(InitState());
14716     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14717
14718     VkVertexInputBindingDescription input_binding;
14719     memset(&input_binding, 0, sizeof(input_binding));
14720
14721     VkVertexInputAttributeDescription input_attrib;
14722     memset(&input_attrib, 0, sizeof(input_attrib));
14723     input_attrib.format = VK_FORMAT_R32_SFLOAT;
14724
14725     char const *vsSource = "#version 450\n"
14726                            "\n"
14727                            "layout(location=0) in int x;\n" /* attrib provided float */
14728                            "out gl_PerVertex {\n"
14729                            "    vec4 gl_Position;\n"
14730                            "};\n"
14731                            "void main(){\n"
14732                            "   gl_Position = vec4(x);\n"
14733                            "}\n";
14734     char const *fsSource = "#version 450\n"
14735                            "\n"
14736                            "layout(location=0) out vec4 color;\n"
14737                            "void main(){\n"
14738                            "   color = vec4(1);\n"
14739                            "}\n";
14740
14741     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14742     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14743
14744     VkPipelineObj pipe(m_device);
14745     pipe.AddColorAttachment();
14746     pipe.AddShader(&vs);
14747     pipe.AddShader(&fs);
14748
14749     pipe.AddVertexInputBindings(&input_binding, 1);
14750     pipe.AddVertexInputAttribs(&input_attrib, 1);
14751
14752     VkDescriptorSetObj descriptorSet(m_device);
14753     descriptorSet.AppendDummy();
14754     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14755
14756     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14757
14758     m_errorMonitor->VerifyFound();
14759 }
14760
14761 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
14762     TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
14763                      "shaders for the same stage");
14764     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14765                                          "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
14766
14767     ASSERT_NO_FATAL_FAILURE(InitState());
14768     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14769
14770     char const *vsSource = "#version 450\n"
14771                            "\n"
14772                            "out gl_PerVertex {\n"
14773                            "    vec4 gl_Position;\n"
14774                            "};\n"
14775                            "void main(){\n"
14776                            "   gl_Position = vec4(1);\n"
14777                            "}\n";
14778     char const *fsSource = "#version 450\n"
14779                            "\n"
14780                            "layout(location=0) out vec4 color;\n"
14781                            "void main(){\n"
14782                            "   color = vec4(1);\n"
14783                            "}\n";
14784
14785     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14786     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14787
14788     VkPipelineObj pipe(m_device);
14789     pipe.AddColorAttachment();
14790     pipe.AddShader(&vs);
14791     pipe.AddShader(&vs);
14792     pipe.AddShader(&fs);
14793
14794     VkDescriptorSetObj descriptorSet(m_device);
14795     descriptorSet.AppendDummy();
14796     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14797
14798     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14799
14800     m_errorMonitor->VerifyFound();
14801 }
14802
14803 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
14804     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
14805                      "as vertex attributes");
14806     m_errorMonitor->ExpectSuccess();
14807
14808     ASSERT_NO_FATAL_FAILURE(InitState());
14809     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14810
14811     VkVertexInputBindingDescription input_binding;
14812     memset(&input_binding, 0, sizeof(input_binding));
14813
14814     VkVertexInputAttributeDescription input_attribs[2];
14815     memset(input_attribs, 0, sizeof(input_attribs));
14816
14817     for (int i = 0; i < 2; i++) {
14818         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14819         input_attribs[i].location = i;
14820     }
14821
14822     char const *vsSource = "#version 450\n"
14823                            "\n"
14824                            "layout(location=0) in mat2x4 x;\n"
14825                            "out gl_PerVertex {\n"
14826                            "    vec4 gl_Position;\n"
14827                            "};\n"
14828                            "void main(){\n"
14829                            "   gl_Position = x[0] + x[1];\n"
14830                            "}\n";
14831     char const *fsSource = "#version 450\n"
14832                            "\n"
14833                            "layout(location=0) out vec4 color;\n"
14834                            "void main(){\n"
14835                            "   color = vec4(1);\n"
14836                            "}\n";
14837
14838     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14839     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14840
14841     VkPipelineObj pipe(m_device);
14842     pipe.AddColorAttachment();
14843     pipe.AddShader(&vs);
14844     pipe.AddShader(&fs);
14845
14846     pipe.AddVertexInputBindings(&input_binding, 1);
14847     pipe.AddVertexInputAttribs(input_attribs, 2);
14848
14849     VkDescriptorSetObj descriptorSet(m_device);
14850     descriptorSet.AppendDummy();
14851     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14852
14853     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14854
14855     /* expect success */
14856     m_errorMonitor->VerifyNotFound();
14857 }
14858
14859 TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
14860     m_errorMonitor->ExpectSuccess();
14861
14862     ASSERT_NO_FATAL_FAILURE(InitState());
14863     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14864
14865     VkVertexInputBindingDescription input_binding;
14866     memset(&input_binding, 0, sizeof(input_binding));
14867
14868     VkVertexInputAttributeDescription input_attribs[2];
14869     memset(input_attribs, 0, sizeof(input_attribs));
14870
14871     for (int i = 0; i < 2; i++) {
14872         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14873         input_attribs[i].location = i;
14874     }
14875
14876     char const *vsSource = "#version 450\n"
14877                            "\n"
14878                            "layout(location=0) in vec4 x[2];\n"
14879                            "out gl_PerVertex {\n"
14880                            "    vec4 gl_Position;\n"
14881                            "};\n"
14882                            "void main(){\n"
14883                            "   gl_Position = x[0] + x[1];\n"
14884                            "}\n";
14885     char const *fsSource = "#version 450\n"
14886                            "\n"
14887                            "layout(location=0) out vec4 color;\n"
14888                            "void main(){\n"
14889                            "   color = vec4(1);\n"
14890                            "}\n";
14891
14892     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14893     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14894
14895     VkPipelineObj pipe(m_device);
14896     pipe.AddColorAttachment();
14897     pipe.AddShader(&vs);
14898     pipe.AddShader(&fs);
14899
14900     pipe.AddVertexInputBindings(&input_binding, 1);
14901     pipe.AddVertexInputAttribs(input_attribs, 2);
14902
14903     VkDescriptorSetObj descriptorSet(m_device);
14904     descriptorSet.AppendDummy();
14905     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14906
14907     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14908
14909     m_errorMonitor->VerifyNotFound();
14910 }
14911
14912 TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
14913     TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
14914                      "through multiple vertex shader inputs, each consuming a different "
14915                      "subset of the components.");
14916     m_errorMonitor->ExpectSuccess();
14917
14918     ASSERT_NO_FATAL_FAILURE(InitState());
14919     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14920
14921     VkVertexInputBindingDescription input_binding;
14922     memset(&input_binding, 0, sizeof(input_binding));
14923
14924     VkVertexInputAttributeDescription input_attribs[3];
14925     memset(input_attribs, 0, sizeof(input_attribs));
14926
14927     for (int i = 0; i < 3; i++) {
14928         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14929         input_attribs[i].location = i;
14930     }
14931
14932     char const *vsSource = "#version 450\n"
14933                            "\n"
14934                            "layout(location=0) in vec4 x;\n"
14935                            "layout(location=1) in vec3 y1;\n"
14936                            "layout(location=1, component=3) in float y2;\n"
14937                            "layout(location=2) in vec4 z;\n"
14938                            "out gl_PerVertex {\n"
14939                            "    vec4 gl_Position;\n"
14940                            "};\n"
14941                            "void main(){\n"
14942                            "   gl_Position = x + vec4(y1, y2) + z;\n"
14943                            "}\n";
14944     char const *fsSource = "#version 450\n"
14945                            "\n"
14946                            "layout(location=0) out vec4 color;\n"
14947                            "void main(){\n"
14948                            "   color = vec4(1);\n"
14949                            "}\n";
14950
14951     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14952     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14953
14954     VkPipelineObj pipe(m_device);
14955     pipe.AddColorAttachment();
14956     pipe.AddShader(&vs);
14957     pipe.AddShader(&fs);
14958
14959     pipe.AddVertexInputBindings(&input_binding, 1);
14960     pipe.AddVertexInputAttribs(input_attribs, 3);
14961
14962     VkDescriptorSetObj descriptorSet(m_device);
14963     descriptorSet.AppendDummy();
14964     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14965
14966     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14967
14968     m_errorMonitor->VerifyNotFound();
14969 }
14970
14971 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
14972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14973                                          "No entrypoint found named `foo`");
14974
14975     ASSERT_NO_FATAL_FAILURE(InitState());
14976     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14977
14978     char const *vsSource = "#version 450\n"
14979                            "out gl_PerVertex {\n"
14980                            "    vec4 gl_Position;\n"
14981                            "};\n"
14982                            "void main(){\n"
14983                            "   gl_Position = vec4(0);\n"
14984                            "}\n";
14985     char const *fsSource = "#version 450\n"
14986                            "\n"
14987                            "layout(location=0) out vec4 color;\n"
14988                            "void main(){\n"
14989                            "   color = vec4(1);\n"
14990                            "}\n";
14991
14992     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14993     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
14994
14995     VkPipelineObj pipe(m_device);
14996     pipe.AddColorAttachment();
14997     pipe.AddShader(&vs);
14998     pipe.AddShader(&fs);
14999
15000     VkDescriptorSetObj descriptorSet(m_device);
15001     descriptorSet.AppendDummy();
15002     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15003
15004     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15005
15006     m_errorMonitor->VerifyFound();
15007 }
15008
15009 TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
15010     m_errorMonitor->ExpectSuccess();
15011
15012     ASSERT_NO_FATAL_FAILURE(InitState());
15013     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15014
15015     char const *vsSource = "#version 450\n"
15016                            "out gl_PerVertex {\n"
15017                            "    vec4 gl_Position;\n"
15018                            "};\n"
15019                            "void main(){\n"
15020                            "   gl_Position = vec4(0);\n"
15021                            "}\n";
15022     char const *fsSource = "#version 450\n"
15023                            "\n"
15024                            "layout(location=0) out vec4 color;\n"
15025                            "void main(){\n"
15026                            "   color = vec4(1);\n"
15027                            "}\n";
15028
15029     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15030     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15031
15032     VkPipelineObj pipe(m_device);
15033     pipe.AddColorAttachment();
15034     pipe.AddShader(&vs);
15035     pipe.AddShader(&fs);
15036
15037     VkDescriptorSetObj descriptorSet(m_device);
15038     descriptorSet.AppendDummy();
15039     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15040
15041     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15042
15043     m_errorMonitor->VerifyNotFound();
15044 }
15045
15046 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
15047     m_errorMonitor->SetDesiredFailureMsg(
15048         VK_DEBUG_REPORT_ERROR_BIT_EXT,
15049         "pDepthStencilState is NULL when rasterization is enabled and subpass "
15050         "uses a depth/stencil attachment");
15051
15052     ASSERT_NO_FATAL_FAILURE(InitState());
15053     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15054
15055     char const *vsSource = "#version 450\n"
15056                            "void main(){ gl_Position = vec4(0); }\n";
15057     char const *fsSource = "#version 450\n"
15058                            "\n"
15059                            "layout(location=0) out vec4 color;\n"
15060                            "void main(){\n"
15061                            "   color = vec4(1);\n"
15062                            "}\n";
15063
15064     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15065     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15066
15067     VkPipelineObj pipe(m_device);
15068     pipe.AddColorAttachment();
15069     pipe.AddShader(&vs);
15070     pipe.AddShader(&fs);
15071
15072     VkDescriptorSetObj descriptorSet(m_device);
15073     descriptorSet.AppendDummy();
15074     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15075
15076     VkAttachmentDescription attachments[] = {
15077         { 0, VK_FORMAT_B8G8R8A8_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_COLOR_ATTACHMENT_OPTIMAL,
15081         },
15082         { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT,
15083           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15084           VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15085           VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
15086         },
15087     };
15088     VkAttachmentReference refs[] = {
15089         { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
15090         { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL },
15091     };
15092     VkSubpassDescription subpass = {
15093         0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
15094         1, &refs[0], nullptr, &refs[1],
15095         0, nullptr
15096     };
15097     VkRenderPassCreateInfo rpci = {
15098         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
15099         0, 2, attachments, 1, &subpass, 0, nullptr
15100     };
15101     VkRenderPass rp;
15102     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15103     ASSERT_VK_SUCCESS(err);
15104
15105     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
15106
15107     m_errorMonitor->VerifyFound();
15108
15109     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15110 }
15111
15112 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
15113     TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
15114                      "set out in 14.1.3: fundamental type must match, and producer side must "
15115                      "have at least as many components");
15116     m_errorMonitor->ExpectSuccess();
15117
15118     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
15119
15120     ASSERT_NO_FATAL_FAILURE(InitState());
15121     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15122
15123     char const *vsSource = "#version 450\n"
15124                            "out gl_PerVertex {\n"
15125                            "    vec4 gl_Position;\n"
15126                            "};\n"
15127                            "layout(location=0) out vec3 x;\n"
15128                            "layout(location=1) out ivec3 y;\n"
15129                            "layout(location=2) out vec3 z;\n"
15130                            "void main(){\n"
15131                            "   gl_Position = vec4(0);\n"
15132                            "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
15133                            "}\n";
15134     char const *fsSource = "#version 450\n"
15135                            "\n"
15136                            "layout(location=0) out vec4 color;\n"
15137                            "layout(location=0) in float x;\n"
15138                            "layout(location=1) flat in int y;\n"
15139                            "layout(location=2) in vec2 z;\n"
15140                            "void main(){\n"
15141                            "   color = vec4(1 + x + y + z.x);\n"
15142                            "}\n";
15143
15144     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15145     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15146
15147     VkPipelineObj pipe(m_device);
15148     pipe.AddColorAttachment();
15149     pipe.AddShader(&vs);
15150     pipe.AddShader(&fs);
15151
15152     VkDescriptorSetObj descriptorSet(m_device);
15153     descriptorSet.AppendDummy();
15154     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15155
15156     VkResult err = VK_SUCCESS;
15157     err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15158     ASSERT_VK_SUCCESS(err);
15159
15160     m_errorMonitor->VerifyNotFound();
15161 }
15162
15163 TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
15164     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
15165                      "passed between the TCS and TES stages");
15166     m_errorMonitor->ExpectSuccess();
15167
15168     ASSERT_NO_FATAL_FAILURE(InitState());
15169     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15170
15171     if (!m_device->phy().features().tessellationShader) {
15172         printf("Device does not support tessellation shaders; skipped.\n");
15173         return;
15174     }
15175
15176     char const *vsSource = "#version 450\n"
15177                            "void main(){}\n";
15178     char const *tcsSource = "#version 450\n"
15179                             "layout(location=0) out int x[];\n"
15180                             "layout(vertices=3) out;\n"
15181                             "void main(){\n"
15182                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15183                             "   gl_TessLevelInner[0] = 1;\n"
15184                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15185                             "}\n";
15186     char const *tesSource = "#version 450\n"
15187                             "layout(triangles, equal_spacing, cw) in;\n"
15188                             "layout(location=0) in int x[];\n"
15189                             "out gl_PerVertex { vec4 gl_Position; };\n"
15190                             "void main(){\n"
15191                             "   gl_Position.xyz = gl_TessCoord;\n"
15192                             "   gl_Position.w = x[0] + x[1] + x[2];\n"
15193                             "}\n";
15194     char const *fsSource = "#version 450\n"
15195                            "layout(location=0) out vec4 color;\n"
15196                            "void main(){\n"
15197                            "   color = vec4(1);\n"
15198                            "}\n";
15199
15200     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15201     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15202     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15203     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15204
15205     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15206                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15207
15208     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15209
15210     VkPipelineObj pipe(m_device);
15211     pipe.SetInputAssembly(&iasci);
15212     pipe.SetTessellation(&tsci);
15213     pipe.AddColorAttachment();
15214     pipe.AddShader(&vs);
15215     pipe.AddShader(&tcs);
15216     pipe.AddShader(&tes);
15217     pipe.AddShader(&fs);
15218
15219     VkDescriptorSetObj descriptorSet(m_device);
15220     descriptorSet.AppendDummy();
15221     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15222
15223     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15224
15225     m_errorMonitor->VerifyNotFound();
15226 }
15227
15228 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
15229     TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
15230                      "interface block passed into the geometry shader. This "
15231                      "is interesting because the 'extra' array level is not "
15232                      "present on the member type, but on the block instance.");
15233     m_errorMonitor->ExpectSuccess();
15234
15235     ASSERT_NO_FATAL_FAILURE(InitState());
15236     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15237
15238     if (!m_device->phy().features().geometryShader) {
15239         printf("Device does not support geometry shaders; skipped.\n");
15240         return;
15241     }
15242
15243     char const *vsSource = "#version 450\n"
15244                            "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
15245                            "void main(){\n"
15246                            "   vs_out.x = vec4(1);\n"
15247                            "}\n";
15248     char const *gsSource = "#version 450\n"
15249                            "layout(triangles) in;\n"
15250                            "layout(triangle_strip, max_vertices=3) out;\n"
15251                            "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
15252                            "out gl_PerVertex { vec4 gl_Position; };\n"
15253                            "void main() {\n"
15254                            "   gl_Position = gs_in[0].x;\n"
15255                            "   EmitVertex();\n"
15256                            "}\n";
15257     char const *fsSource = "#version 450\n"
15258                            "layout(location=0) out vec4 color;\n"
15259                            "void main(){\n"
15260                            "   color = vec4(1);\n"
15261                            "}\n";
15262
15263     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15264     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
15265     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15266
15267     VkPipelineObj pipe(m_device);
15268     pipe.AddColorAttachment();
15269     pipe.AddShader(&vs);
15270     pipe.AddShader(&gs);
15271     pipe.AddShader(&fs);
15272
15273     VkDescriptorSetObj descriptorSet(m_device);
15274     descriptorSet.AppendDummy();
15275     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15276
15277     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15278
15279     m_errorMonitor->VerifyNotFound();
15280 }
15281
15282 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
15283     TEST_DESCRIPTION("Test that an error is produced for a variable output from "
15284                      "the TCS without the patch decoration, but consumed in the TES "
15285                      "with the decoration.");
15286     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage "
15287                                                                         "but per-patch in tessellation evaluation shader stage");
15288
15289     ASSERT_NO_FATAL_FAILURE(InitState());
15290     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15291
15292     if (!m_device->phy().features().tessellationShader) {
15293         printf("Device does not support tessellation shaders; skipped.\n");
15294         return;
15295     }
15296
15297     char const *vsSource = "#version 450\n"
15298                            "void main(){}\n";
15299     char const *tcsSource = "#version 450\n"
15300                             "layout(location=0) out int x[];\n"
15301                             "layout(vertices=3) out;\n"
15302                             "void main(){\n"
15303                             "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15304                             "   gl_TessLevelInner[0] = 1;\n"
15305                             "   x[gl_InvocationID] = gl_InvocationID;\n"
15306                             "}\n";
15307     char const *tesSource = "#version 450\n"
15308                             "layout(triangles, equal_spacing, cw) in;\n"
15309                             "layout(location=0) patch in int x;\n"
15310                             "out gl_PerVertex { vec4 gl_Position; };\n"
15311                             "void main(){\n"
15312                             "   gl_Position.xyz = gl_TessCoord;\n"
15313                             "   gl_Position.w = x;\n"
15314                             "}\n";
15315     char const *fsSource = "#version 450\n"
15316                            "layout(location=0) out vec4 color;\n"
15317                            "void main(){\n"
15318                            "   color = vec4(1);\n"
15319                            "}\n";
15320
15321     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15322     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15323     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15324     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15325
15326     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15327                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15328
15329     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15330
15331     VkPipelineObj pipe(m_device);
15332     pipe.SetInputAssembly(&iasci);
15333     pipe.SetTessellation(&tsci);
15334     pipe.AddColorAttachment();
15335     pipe.AddShader(&vs);
15336     pipe.AddShader(&tcs);
15337     pipe.AddShader(&tes);
15338     pipe.AddShader(&fs);
15339
15340     VkDescriptorSetObj descriptorSet(m_device);
15341     descriptorSet.AppendDummy();
15342     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15343
15344     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15345
15346     m_errorMonitor->VerifyFound();
15347 }
15348
15349 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
15350     TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
15351                      "bindings provide the same location");
15352     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15353                                          "Duplicate vertex input binding descriptions for binding 0");
15354
15355     ASSERT_NO_FATAL_FAILURE(InitState());
15356     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15357
15358     /* Two binding descriptions for binding 0 */
15359     VkVertexInputBindingDescription input_bindings[2];
15360     memset(input_bindings, 0, sizeof(input_bindings));
15361
15362     VkVertexInputAttributeDescription input_attrib;
15363     memset(&input_attrib, 0, sizeof(input_attrib));
15364     input_attrib.format = VK_FORMAT_R32_SFLOAT;
15365
15366     char const *vsSource = "#version 450\n"
15367                            "\n"
15368                            "layout(location=0) in float x;\n" /* attrib provided float */
15369                            "out gl_PerVertex {\n"
15370                            "    vec4 gl_Position;\n"
15371                            "};\n"
15372                            "void main(){\n"
15373                            "   gl_Position = vec4(x);\n"
15374                            "}\n";
15375     char const *fsSource = "#version 450\n"
15376                            "\n"
15377                            "layout(location=0) out vec4 color;\n"
15378                            "void main(){\n"
15379                            "   color = vec4(1);\n"
15380                            "}\n";
15381
15382     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15383     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15384
15385     VkPipelineObj pipe(m_device);
15386     pipe.AddColorAttachment();
15387     pipe.AddShader(&vs);
15388     pipe.AddShader(&fs);
15389
15390     pipe.AddVertexInputBindings(input_bindings, 2);
15391     pipe.AddVertexInputAttribs(&input_attrib, 1);
15392
15393     VkDescriptorSetObj descriptorSet(m_device);
15394     descriptorSet.AppendDummy();
15395     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15396
15397     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15398
15399     m_errorMonitor->VerifyFound();
15400 }
15401
15402 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
15403     TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
15404                      "attributes. This is interesting because they consume multiple "
15405                      "locations.");
15406     m_errorMonitor->ExpectSuccess();
15407
15408     ASSERT_NO_FATAL_FAILURE(InitState());
15409     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15410
15411     if (!m_device->phy().features().shaderFloat64) {
15412         printf("Device does not support 64bit vertex attributes; skipped.\n");
15413         return;
15414     }
15415
15416     VkVertexInputBindingDescription input_bindings[1];
15417     memset(input_bindings, 0, sizeof(input_bindings));
15418
15419     VkVertexInputAttributeDescription input_attribs[4];
15420     memset(input_attribs, 0, sizeof(input_attribs));
15421     input_attribs[0].location = 0;
15422     input_attribs[0].offset = 0;
15423     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15424     input_attribs[1].location = 2;
15425     input_attribs[1].offset = 32;
15426     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15427     input_attribs[2].location = 4;
15428     input_attribs[2].offset = 64;
15429     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15430     input_attribs[3].location = 6;
15431     input_attribs[3].offset = 96;
15432     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15433
15434     char const *vsSource = "#version 450\n"
15435                            "\n"
15436                            "layout(location=0) in dmat4 x;\n"
15437                            "out gl_PerVertex {\n"
15438                            "    vec4 gl_Position;\n"
15439                            "};\n"
15440                            "void main(){\n"
15441                            "   gl_Position = vec4(x[0][0]);\n"
15442                            "}\n";
15443     char const *fsSource = "#version 450\n"
15444                            "\n"
15445                            "layout(location=0) out vec4 color;\n"
15446                            "void main(){\n"
15447                            "   color = vec4(1);\n"
15448                            "}\n";
15449
15450     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15451     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15452
15453     VkPipelineObj pipe(m_device);
15454     pipe.AddColorAttachment();
15455     pipe.AddShader(&vs);
15456     pipe.AddShader(&fs);
15457
15458     pipe.AddVertexInputBindings(input_bindings, 1);
15459     pipe.AddVertexInputAttribs(input_attribs, 4);
15460
15461     VkDescriptorSetObj descriptorSet(m_device);
15462     descriptorSet.AppendDummy();
15463     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15464
15465     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15466
15467     m_errorMonitor->VerifyNotFound();
15468 }
15469
15470 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
15471     TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
15472                      "provide an output for one of the pipeline's color attachments");
15473     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
15474
15475     ASSERT_NO_FATAL_FAILURE(InitState());
15476
15477     char const *vsSource = "#version 450\n"
15478                            "\n"
15479                            "out gl_PerVertex {\n"
15480                            "    vec4 gl_Position;\n"
15481                            "};\n"
15482                            "void main(){\n"
15483                            "   gl_Position = vec4(1);\n"
15484                            "}\n";
15485     char const *fsSource = "#version 450\n"
15486                            "\n"
15487                            "void main(){\n"
15488                            "}\n";
15489
15490     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15491     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15492
15493     VkPipelineObj pipe(m_device);
15494     pipe.AddShader(&vs);
15495     pipe.AddShader(&fs);
15496
15497     /* set up CB 0, not written */
15498     pipe.AddColorAttachment();
15499     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15500
15501     VkDescriptorSetObj descriptorSet(m_device);
15502     descriptorSet.AppendDummy();
15503     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15504
15505     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15506
15507     m_errorMonitor->VerifyFound();
15508 }
15509
15510 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
15511     TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
15512                      "output with no matching attachment");
15513     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
15514                                          "FS writes to output location 1 with no matching attachment");
15515
15516     ASSERT_NO_FATAL_FAILURE(InitState());
15517
15518     char const *vsSource = "#version 450\n"
15519                            "\n"
15520                            "out gl_PerVertex {\n"
15521                            "    vec4 gl_Position;\n"
15522                            "};\n"
15523                            "void main(){\n"
15524                            "   gl_Position = vec4(1);\n"
15525                            "}\n";
15526     char const *fsSource = "#version 450\n"
15527                            "\n"
15528                            "layout(location=0) out vec4 x;\n"
15529                            "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
15530                            "void main(){\n"
15531                            "   x = vec4(1);\n"
15532                            "   y = vec4(1);\n"
15533                            "}\n";
15534
15535     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15536     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15537
15538     VkPipelineObj pipe(m_device);
15539     pipe.AddShader(&vs);
15540     pipe.AddShader(&fs);
15541
15542     /* set up CB 0, not written */
15543     pipe.AddColorAttachment();
15544     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15545     /* FS writes CB 1, but we don't configure it */
15546
15547     VkDescriptorSetObj descriptorSet(m_device);
15548     descriptorSet.AppendDummy();
15549     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15550
15551     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15552
15553     m_errorMonitor->VerifyFound();
15554 }
15555
15556 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
15557     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
15558                      "type of an FS output variable, and the format of the corresponding attachment");
15559     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
15560
15561     ASSERT_NO_FATAL_FAILURE(InitState());
15562
15563     char const *vsSource = "#version 450\n"
15564                            "\n"
15565                            "out gl_PerVertex {\n"
15566                            "    vec4 gl_Position;\n"
15567                            "};\n"
15568                            "void main(){\n"
15569                            "   gl_Position = vec4(1);\n"
15570                            "}\n";
15571     char const *fsSource = "#version 450\n"
15572                            "\n"
15573                            "layout(location=0) out ivec4 x;\n" /* not UNORM */
15574                            "void main(){\n"
15575                            "   x = ivec4(1);\n"
15576                            "}\n";
15577
15578     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15579     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15580
15581     VkPipelineObj pipe(m_device);
15582     pipe.AddShader(&vs);
15583     pipe.AddShader(&fs);
15584
15585     /* set up CB 0; type is UNORM by default */
15586     pipe.AddColorAttachment();
15587     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15588
15589     VkDescriptorSetObj descriptorSet(m_device);
15590     descriptorSet.AppendDummy();
15591     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15592
15593     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15594
15595     m_errorMonitor->VerifyFound();
15596 }
15597
15598 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
15599     TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
15600                      "block which has no corresponding binding in the pipeline layout");
15601     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
15602
15603     ASSERT_NO_FATAL_FAILURE(InitState());
15604
15605     char const *vsSource = "#version 450\n"
15606                            "\n"
15607                            "out gl_PerVertex {\n"
15608                            "    vec4 gl_Position;\n"
15609                            "};\n"
15610                            "void main(){\n"
15611                            "   gl_Position = vec4(1);\n"
15612                            "}\n";
15613     char const *fsSource = "#version 450\n"
15614                            "\n"
15615                            "layout(location=0) out vec4 x;\n"
15616                            "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
15617                            "void main(){\n"
15618                            "   x = vec4(bar.y);\n"
15619                            "}\n";
15620
15621     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15622     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15623
15624     VkPipelineObj pipe(m_device);
15625     pipe.AddShader(&vs);
15626     pipe.AddShader(&fs);
15627
15628     /* set up CB 0; type is UNORM by default */
15629     pipe.AddColorAttachment();
15630     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15631
15632     VkDescriptorSetObj descriptorSet(m_device);
15633     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15634
15635     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15636
15637     m_errorMonitor->VerifyFound();
15638 }
15639
15640 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
15641     TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
15642                      "which are not provided in the pipeline layout");
15643     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
15644
15645     ASSERT_NO_FATAL_FAILURE(InitState());
15646
15647     char const *vsSource = "#version 450\n"
15648                            "\n"
15649                            "layout(push_constant, std430) uniform foo { float x; } consts;\n"
15650                            "out gl_PerVertex {\n"
15651                            "    vec4 gl_Position;\n"
15652                            "};\n"
15653                            "void main(){\n"
15654                            "   gl_Position = vec4(consts.x);\n"
15655                            "}\n";
15656     char const *fsSource = "#version 450\n"
15657                            "\n"
15658                            "layout(location=0) out vec4 x;\n"
15659                            "void main(){\n"
15660                            "   x = vec4(1);\n"
15661                            "}\n";
15662
15663     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15664     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15665
15666     VkPipelineObj pipe(m_device);
15667     pipe.AddShader(&vs);
15668     pipe.AddShader(&fs);
15669
15670     /* set up CB 0; type is UNORM by default */
15671     pipe.AddColorAttachment();
15672     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15673
15674     VkDescriptorSetObj descriptorSet(m_device);
15675     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15676
15677     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15678
15679     /* should have generated an error -- no push constant ranges provided! */
15680     m_errorMonitor->VerifyFound();
15681 }
15682
15683 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
15684     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15685                      "which is not included in the subpass description");
15686     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15687                                          "consumes input attachment index 0 but not provided in subpass");
15688
15689     ASSERT_NO_FATAL_FAILURE(InitState());
15690
15691     char const *vsSource = "#version 450\n"
15692                            "\n"
15693                            "out gl_PerVertex {\n"
15694                            "    vec4 gl_Position;\n"
15695                            "};\n"
15696                            "void main(){\n"
15697                            "    gl_Position = vec4(1);\n"
15698                            "}\n";
15699     char const *fsSource = "#version 450\n"
15700                            "\n"
15701                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15702                            "layout(location=0) out vec4 color;\n"
15703                            "void main() {\n"
15704                            "   color = subpassLoad(x);\n"
15705                            "}\n";
15706
15707     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15708     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15709
15710     VkPipelineObj pipe(m_device);
15711     pipe.AddShader(&vs);
15712     pipe.AddShader(&fs);
15713     pipe.AddColorAttachment();
15714     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15715
15716     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15717     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15718     VkDescriptorSetLayout dsl;
15719     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15720     ASSERT_VK_SUCCESS(err);
15721
15722     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15723     VkPipelineLayout pl;
15724     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15725     ASSERT_VK_SUCCESS(err);
15726
15727     // error here.
15728     pipe.CreateVKPipeline(pl, renderPass());
15729
15730     m_errorMonitor->VerifyFound();
15731
15732     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15733     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15734 }
15735
15736 TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
15737     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
15738     m_errorMonitor->ExpectSuccess();
15739
15740     ASSERT_NO_FATAL_FAILURE(InitState());
15741
15742     char const *vsSource = "#version 450\n"
15743                            "\n"
15744                            "out gl_PerVertex {\n"
15745                            "    vec4 gl_Position;\n"
15746                            "};\n"
15747                            "void main(){\n"
15748                            "    gl_Position = vec4(1);\n"
15749                            "}\n";
15750     char const *fsSource = "#version 450\n"
15751                            "\n"
15752                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15753                            "layout(location=0) out vec4 color;\n"
15754                            "void main() {\n"
15755                            "   color = subpassLoad(x);\n"
15756                            "}\n";
15757
15758     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15759     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15760
15761     VkPipelineObj pipe(m_device);
15762     pipe.AddShader(&vs);
15763     pipe.AddShader(&fs);
15764     pipe.AddColorAttachment();
15765     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15766
15767     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15768     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15769     VkDescriptorSetLayout dsl;
15770     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15771     ASSERT_VK_SUCCESS(err);
15772
15773     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15774     VkPipelineLayout pl;
15775     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15776     ASSERT_VK_SUCCESS(err);
15777
15778     VkAttachmentDescription descs[2] = {
15779         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15780          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15781          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15782         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15783          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15784     };
15785     VkAttachmentReference color = {
15786         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15787     };
15788     VkAttachmentReference input = {
15789         1, VK_IMAGE_LAYOUT_GENERAL,
15790     };
15791
15792     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15793
15794     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15795     VkRenderPass rp;
15796     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15797     ASSERT_VK_SUCCESS(err);
15798
15799     // should be OK. would go wrong here if it's going to...
15800     pipe.CreateVKPipeline(pl, rp);
15801
15802     m_errorMonitor->VerifyNotFound();
15803
15804     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15805     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15806     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15807 }
15808
15809 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
15810     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15811                      "with a format having a different fundamental type");
15812     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15813                                          "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
15814
15815     ASSERT_NO_FATAL_FAILURE(InitState());
15816
15817     char const *vsSource = "#version 450\n"
15818                            "\n"
15819                            "out gl_PerVertex {\n"
15820                            "    vec4 gl_Position;\n"
15821                            "};\n"
15822                            "void main(){\n"
15823                            "    gl_Position = vec4(1);\n"
15824                            "}\n";
15825     char const *fsSource = "#version 450\n"
15826                            "\n"
15827                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15828                            "layout(location=0) out vec4 color;\n"
15829                            "void main() {\n"
15830                            "   color = subpassLoad(x);\n"
15831                            "}\n";
15832
15833     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15834     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15835
15836     VkPipelineObj pipe(m_device);
15837     pipe.AddShader(&vs);
15838     pipe.AddShader(&fs);
15839     pipe.AddColorAttachment();
15840     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15841
15842     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15843     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15844     VkDescriptorSetLayout dsl;
15845     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15846     ASSERT_VK_SUCCESS(err);
15847
15848     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15849     VkPipelineLayout pl;
15850     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15851     ASSERT_VK_SUCCESS(err);
15852
15853     VkAttachmentDescription descs[2] = {
15854         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15855          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15856          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15857         {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15858          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15859     };
15860     VkAttachmentReference color = {
15861         0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15862     };
15863     VkAttachmentReference input = {
15864         1, VK_IMAGE_LAYOUT_GENERAL,
15865     };
15866
15867     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15868
15869     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15870     VkRenderPass rp;
15871     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15872     ASSERT_VK_SUCCESS(err);
15873
15874     // error here.
15875     pipe.CreateVKPipeline(pl, rp);
15876
15877     m_errorMonitor->VerifyFound();
15878
15879     vkDestroyRenderPass(m_device->device(), rp, nullptr);
15880     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15881     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15882 }
15883
15884 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
15885     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15886                      "which is not included in the subpass description -- array case");
15887     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15888                                          "consumes input attachment index 1 but not provided in subpass");
15889
15890     ASSERT_NO_FATAL_FAILURE(InitState());
15891
15892     char const *vsSource = "#version 450\n"
15893                            "\n"
15894                            "out gl_PerVertex {\n"
15895                            "    vec4 gl_Position;\n"
15896                            "};\n"
15897                            "void main(){\n"
15898                            "    gl_Position = vec4(1);\n"
15899                            "}\n";
15900     char const *fsSource = "#version 450\n"
15901                            "\n"
15902                            "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n"
15903                            "layout(location=0) out vec4 color;\n"
15904                            "void main() {\n"
15905                            "   color = subpassLoad(xs[1]);\n"
15906                            "}\n";
15907
15908     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15909     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15910
15911     VkPipelineObj pipe(m_device);
15912     pipe.AddShader(&vs);
15913     pipe.AddShader(&fs);
15914     pipe.AddColorAttachment();
15915     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15916
15917     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15918     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15919     VkDescriptorSetLayout dsl;
15920     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15921     ASSERT_VK_SUCCESS(err);
15922
15923     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15924     VkPipelineLayout pl;
15925     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15926     ASSERT_VK_SUCCESS(err);
15927
15928     // error here.
15929     pipe.CreateVKPipeline(pl, renderPass());
15930
15931     m_errorMonitor->VerifyFound();
15932
15933     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15934     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15935 }
15936
15937 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
15938     TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
15939                      "descriptor which is not provided in the pipeline layout");
15940     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
15941
15942     ASSERT_NO_FATAL_FAILURE(InitState());
15943
15944     char const *csSource = "#version 450\n"
15945                            "\n"
15946                            "layout(local_size_x=1) in;\n"
15947                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15948                            "void main(){\n"
15949                            "   x = vec4(1);\n"
15950                            "}\n";
15951
15952     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15953
15954     VkDescriptorSetObj descriptorSet(m_device);
15955     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15956
15957     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15958                                         nullptr,
15959                                         0,
15960                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15961                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15962                                         descriptorSet.GetPipelineLayout(),
15963                                         VK_NULL_HANDLE,
15964                                         -1};
15965
15966     VkPipeline pipe;
15967     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
15968
15969     m_errorMonitor->VerifyFound();
15970
15971     if (err == VK_SUCCESS) {
15972         vkDestroyPipeline(m_device->device(), pipe, nullptr);
15973     }
15974 }
15975
15976 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
15977     TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
15978                      "descriptor-backed resource which is not provided, but the shader does not "
15979                      "statically use it. This is interesting because it requires compute pipelines "
15980                      "to have a proper descriptor use walk, which they didn't for some time.");
15981     m_errorMonitor->ExpectSuccess();
15982
15983     ASSERT_NO_FATAL_FAILURE(InitState());
15984
15985     char const *csSource = "#version 450\n"
15986                            "\n"
15987                            "layout(local_size_x=1) in;\n"
15988                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15989                            "void main(){\n"
15990                            "   // x is not used.\n"
15991                            "}\n";
15992
15993     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15994
15995     VkDescriptorSetObj descriptorSet(m_device);
15996     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15997
15998     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15999                                         nullptr,
16000                                         0,
16001                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16002                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16003                                         descriptorSet.GetPipelineLayout(),
16004                                         VK_NULL_HANDLE,
16005                                         -1};
16006
16007     VkPipeline pipe;
16008     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16009
16010     m_errorMonitor->VerifyNotFound();
16011
16012     if (err == VK_SUCCESS) {
16013         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16014     }
16015 }
16016
16017 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
16018     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
16019                      "descriptor-backed resource of a mismatched type");
16020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16021                                          "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
16022
16023     ASSERT_NO_FATAL_FAILURE(InitState());
16024
16025     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
16026     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding};
16027     VkDescriptorSetLayout dsl;
16028     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16029     ASSERT_VK_SUCCESS(err);
16030
16031     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16032     VkPipelineLayout pl;
16033     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16034     ASSERT_VK_SUCCESS(err);
16035
16036     char const *csSource = "#version 450\n"
16037                            "\n"
16038                            "layout(local_size_x=1) in;\n"
16039                            "layout(set=0, binding=0) buffer block { vec4 x; };\n"
16040                            "void main() {\n"
16041                            "   x.x = 1.0f;\n"
16042                            "}\n";
16043     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16044
16045     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16046                                         nullptr,
16047                                         0,
16048                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16049                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16050                                         pl,
16051                                         VK_NULL_HANDLE,
16052                                         -1};
16053
16054     VkPipeline pipe;
16055     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16056
16057     m_errorMonitor->VerifyFound();
16058
16059     if (err == VK_SUCCESS) {
16060         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16061     }
16062
16063     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16064     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16065 }
16066
16067 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
16068     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16069                      "sampler portion of a combined image + sampler");
16070     m_errorMonitor->ExpectSuccess();
16071
16072     ASSERT_NO_FATAL_FAILURE(InitState());
16073
16074     VkDescriptorSetLayoutBinding bindings[] = {
16075         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16076         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16077         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16078     };
16079     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16080     VkDescriptorSetLayout dsl;
16081     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16082     ASSERT_VK_SUCCESS(err);
16083
16084     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16085     VkPipelineLayout pl;
16086     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16087     ASSERT_VK_SUCCESS(err);
16088
16089     char const *csSource = "#version 450\n"
16090                            "\n"
16091                            "layout(local_size_x=1) in;\n"
16092                            "layout(set=0, binding=0) uniform sampler s;\n"
16093                            "layout(set=0, binding=1) uniform texture2D t;\n"
16094                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16095                            "void main() {\n"
16096                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16097                            "}\n";
16098     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16099
16100     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16101                                         nullptr,
16102                                         0,
16103                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16104                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16105                                         pl,
16106                                         VK_NULL_HANDLE,
16107                                         -1};
16108
16109     VkPipeline pipe;
16110     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16111
16112     m_errorMonitor->VerifyNotFound();
16113
16114     if (err == VK_SUCCESS) {
16115         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16116     }
16117
16118     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16119     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16120 }
16121
16122 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
16123     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16124                      "image portion of a combined image + sampler");
16125     m_errorMonitor->ExpectSuccess();
16126
16127     ASSERT_NO_FATAL_FAILURE(InitState());
16128
16129     VkDescriptorSetLayoutBinding bindings[] = {
16130         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16131         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16132         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16133     };
16134     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16135     VkDescriptorSetLayout dsl;
16136     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16137     ASSERT_VK_SUCCESS(err);
16138
16139     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16140     VkPipelineLayout pl;
16141     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16142     ASSERT_VK_SUCCESS(err);
16143
16144     char const *csSource = "#version 450\n"
16145                            "\n"
16146                            "layout(local_size_x=1) in;\n"
16147                            "layout(set=0, binding=0) uniform texture2D t;\n"
16148                            "layout(set=0, binding=1) uniform sampler s;\n"
16149                            "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16150                            "void main() {\n"
16151                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16152                            "}\n";
16153     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16154
16155     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16156                                         nullptr,
16157                                         0,
16158                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16159                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16160                                         pl,
16161                                         VK_NULL_HANDLE,
16162                                         -1};
16163
16164     VkPipeline pipe;
16165     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16166
16167     m_errorMonitor->VerifyNotFound();
16168
16169     if (err == VK_SUCCESS) {
16170         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16171     }
16172
16173     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16174     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16175 }
16176
16177 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
16178     TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
16179                      "both the sampler and the image of a combined image+sampler "
16180                      "but via separate variables");
16181     m_errorMonitor->ExpectSuccess();
16182
16183     ASSERT_NO_FATAL_FAILURE(InitState());
16184
16185     VkDescriptorSetLayoutBinding bindings[] = {
16186         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16187         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16188     };
16189     VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
16190     VkDescriptorSetLayout dsl;
16191     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16192     ASSERT_VK_SUCCESS(err);
16193
16194     VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16195     VkPipelineLayout pl;
16196     err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16197     ASSERT_VK_SUCCESS(err);
16198
16199     char const *csSource = "#version 450\n"
16200                            "\n"
16201                            "layout(local_size_x=1) in;\n"
16202                            "layout(set=0, binding=0) uniform texture2D t;\n"
16203                            "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
16204                            "layout(set=0, binding=1) buffer block { vec4 x; };\n"
16205                            "void main() {\n"
16206                            "   x = texture(sampler2D(t, s), vec2(0));\n"
16207                            "}\n";
16208     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16209
16210     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16211                                         nullptr,
16212                                         0,
16213                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16214                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16215                                         pl,
16216                                         VK_NULL_HANDLE,
16217                                         -1};
16218
16219     VkPipeline pipe;
16220     err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16221
16222     m_errorMonitor->VerifyNotFound();
16223
16224     if (err == VK_SUCCESS) {
16225         vkDestroyPipeline(m_device->device(), pipe, nullptr);
16226     }
16227
16228     vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16229     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16230 }
16231
16232 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
16233     TEST_DESCRIPTION("Test that an error is produced when an image view type "
16234                      "does not match the dimensionality declared in the shader");
16235
16236     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
16237
16238     ASSERT_NO_FATAL_FAILURE(InitState());
16239     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16240
16241     char const *vsSource = "#version 450\n"
16242                            "\n"
16243                            "out gl_PerVertex { vec4 gl_Position; };\n"
16244                            "void main() { gl_Position = vec4(0); }\n";
16245     char const *fsSource = "#version 450\n"
16246                            "\n"
16247                            "layout(set=0, binding=0) uniform sampler3D s;\n"
16248                            "layout(location=0) out vec4 color;\n"
16249                            "void main() {\n"
16250                            "   color = texture(s, vec3(0));\n"
16251                            "}\n";
16252     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16253     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16254
16255     VkPipelineObj pipe(m_device);
16256     pipe.AddShader(&vs);
16257     pipe.AddShader(&fs);
16258     pipe.AddColorAttachment();
16259
16260     VkTextureObj texture(m_device, nullptr);
16261     VkSamplerObj sampler(m_device);
16262
16263     VkDescriptorSetObj descriptorSet(m_device);
16264     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16265     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16266
16267     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16268     ASSERT_VK_SUCCESS(err);
16269
16270     BeginCommandBuffer();
16271
16272     m_commandBuffer->BindPipeline(pipe);
16273     m_commandBuffer->BindDescriptorSet(descriptorSet);
16274
16275     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16276     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16277     VkRect2D scissor = {{0, 0}, {16, 16}};
16278     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16279
16280     // error produced here.
16281     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16282
16283     m_errorMonitor->VerifyFound();
16284
16285     EndCommandBuffer();
16286 }
16287
16288 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
16289     TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
16290                      "are consumed via singlesample images types in the shader, or vice versa.");
16291
16292     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
16293
16294     ASSERT_NO_FATAL_FAILURE(InitState());
16295     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16296
16297     char const *vsSource = "#version 450\n"
16298                            "\n"
16299                            "out gl_PerVertex { vec4 gl_Position; };\n"
16300                            "void main() { gl_Position = vec4(0); }\n";
16301     char const *fsSource = "#version 450\n"
16302                            "\n"
16303                            "layout(set=0, binding=0) uniform sampler2DMS s;\n"
16304                            "layout(location=0) out vec4 color;\n"
16305                            "void main() {\n"
16306                            "   color = texelFetch(s, ivec2(0), 0);\n"
16307                            "}\n";
16308     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16309     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16310
16311     VkPipelineObj pipe(m_device);
16312     pipe.AddShader(&vs);
16313     pipe.AddShader(&fs);
16314     pipe.AddColorAttachment();
16315
16316     VkTextureObj texture(m_device, nullptr);
16317     VkSamplerObj sampler(m_device);
16318
16319     VkDescriptorSetObj descriptorSet(m_device);
16320     descriptorSet.AppendSamplerTexture(&sampler, &texture);
16321     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16322
16323     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16324     ASSERT_VK_SUCCESS(err);
16325
16326     BeginCommandBuffer();
16327
16328     m_commandBuffer->BindPipeline(pipe);
16329     m_commandBuffer->BindDescriptorSet(descriptorSet);
16330
16331     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16332     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16333     VkRect2D scissor = {{0, 0}, {16, 16}};
16334     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16335
16336     // error produced here.
16337     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16338
16339     m_errorMonitor->VerifyFound();
16340
16341     EndCommandBuffer();
16342 }
16343
16344 #endif // SHADER_CHECKER_TESTS
16345
16346 #if DEVICE_LIMITS_TESTS
16347 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) {
16348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16349
16350     ASSERT_NO_FATAL_FAILURE(InitState());
16351
16352     // Create an image
16353     VkImage image;
16354
16355     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16356     const int32_t tex_width = 32;
16357     const int32_t tex_height = 32;
16358
16359     VkImageCreateInfo image_create_info = {};
16360     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16361     image_create_info.pNext = NULL;
16362     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16363     image_create_info.format = tex_format;
16364     image_create_info.extent.width = tex_width;
16365     image_create_info.extent.height = tex_height;
16366     image_create_info.extent.depth = 1;
16367     image_create_info.mipLevels = 1;
16368     image_create_info.arrayLayers = 1;
16369     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16370     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16371     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16372     image_create_info.flags = 0;
16373
16374     // Introduce error by sending down a bogus width extent
16375     image_create_info.extent.width = 65536;
16376     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16377
16378     m_errorMonitor->VerifyFound();
16379 }
16380
16381 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) {
16382     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16383                                          "CreateImage extents is 0 for at least one required dimension");
16384
16385     ASSERT_NO_FATAL_FAILURE(InitState());
16386
16387     // Create an image
16388     VkImage image;
16389
16390     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16391     const int32_t tex_width = 32;
16392     const int32_t tex_height = 32;
16393
16394     VkImageCreateInfo image_create_info = {};
16395     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16396     image_create_info.pNext = NULL;
16397     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16398     image_create_info.format = tex_format;
16399     image_create_info.extent.width = tex_width;
16400     image_create_info.extent.height = tex_height;
16401     image_create_info.extent.depth = 1;
16402     image_create_info.mipLevels = 1;
16403     image_create_info.arrayLayers = 1;
16404     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16405     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16406     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16407     image_create_info.flags = 0;
16408
16409     // Introduce error by sending down a bogus width extent
16410     image_create_info.extent.width = 0;
16411     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16412
16413     m_errorMonitor->VerifyFound();
16414 }
16415 #endif // DEVICE_LIMITS_TESTS
16416
16417 #if IMAGE_TESTS
16418 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
16419     TEST_DESCRIPTION("Create a render pass with an attachment description "
16420                      "format set to VK_FORMAT_UNDEFINED");
16421
16422     ASSERT_NO_FATAL_FAILURE(InitState());
16423     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16424
16425     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
16426
16427     VkAttachmentReference color_attach = {};
16428     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
16429     color_attach.attachment = 0;
16430     VkSubpassDescription subpass = {};
16431     subpass.colorAttachmentCount = 1;
16432     subpass.pColorAttachments = &color_attach;
16433
16434     VkRenderPassCreateInfo rpci = {};
16435     rpci.subpassCount = 1;
16436     rpci.pSubpasses = &subpass;
16437     rpci.attachmentCount = 1;
16438     VkAttachmentDescription attach_desc = {};
16439     attach_desc.format = VK_FORMAT_UNDEFINED;
16440     rpci.pAttachments = &attach_desc;
16441     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16442     VkRenderPass rp;
16443     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16444
16445     m_errorMonitor->VerifyFound();
16446
16447     if (result == VK_SUCCESS) {
16448         vkDestroyRenderPass(m_device->device(), rp, NULL);
16449     }
16450 }
16451
16452 TEST_F(VkLayerTest, InvalidImageView) {
16453     VkResult err;
16454
16455     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 ");
16456
16457     ASSERT_NO_FATAL_FAILURE(InitState());
16458
16459     // Create an image and try to create a view with bad baseMipLevel
16460     VkImage image;
16461
16462     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16463     const int32_t tex_width = 32;
16464     const int32_t tex_height = 32;
16465
16466     VkImageCreateInfo image_create_info = {};
16467     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16468     image_create_info.pNext = NULL;
16469     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16470     image_create_info.format = tex_format;
16471     image_create_info.extent.width = tex_width;
16472     image_create_info.extent.height = tex_height;
16473     image_create_info.extent.depth = 1;
16474     image_create_info.mipLevels = 1;
16475     image_create_info.arrayLayers = 1;
16476     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16477     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16478     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16479     image_create_info.flags = 0;
16480
16481     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16482     ASSERT_VK_SUCCESS(err);
16483
16484     VkImageViewCreateInfo image_view_create_info = {};
16485     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16486     image_view_create_info.image = image;
16487     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16488     image_view_create_info.format = tex_format;
16489     image_view_create_info.subresourceRange.layerCount = 1;
16490     image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error
16491     image_view_create_info.subresourceRange.levelCount = 1;
16492     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16493
16494     VkImageView view;
16495     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16496
16497     m_errorMonitor->VerifyFound();
16498     vkDestroyImage(m_device->device(), image, NULL);
16499 }
16500
16501 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
16502     VkResult err;
16503     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16504                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
16505
16506     ASSERT_NO_FATAL_FAILURE(InitState());
16507
16508     // Create an image and try to create a view with no memory backing the image
16509     VkImage image;
16510
16511     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16512     const int32_t tex_width = 32;
16513     const int32_t tex_height = 32;
16514
16515     VkImageCreateInfo image_create_info = {};
16516     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16517     image_create_info.pNext = NULL;
16518     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16519     image_create_info.format = tex_format;
16520     image_create_info.extent.width = tex_width;
16521     image_create_info.extent.height = tex_height;
16522     image_create_info.extent.depth = 1;
16523     image_create_info.mipLevels = 1;
16524     image_create_info.arrayLayers = 1;
16525     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16526     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16527     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16528     image_create_info.flags = 0;
16529
16530     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16531     ASSERT_VK_SUCCESS(err);
16532
16533     VkImageViewCreateInfo image_view_create_info = {};
16534     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16535     image_view_create_info.image = image;
16536     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16537     image_view_create_info.format = tex_format;
16538     image_view_create_info.subresourceRange.layerCount = 1;
16539     image_view_create_info.subresourceRange.baseMipLevel = 0;
16540     image_view_create_info.subresourceRange.levelCount = 1;
16541     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16542
16543     VkImageView view;
16544     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16545
16546     m_errorMonitor->VerifyFound();
16547     vkDestroyImage(m_device->device(), image, NULL);
16548     // If last error is success, it still created the view, so delete it.
16549     if (err == VK_SUCCESS) {
16550         vkDestroyImageView(m_device->device(), view, NULL);
16551     }
16552 }
16553
16554 TEST_F(VkLayerTest, InvalidImageViewAspect) {
16555     TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
16556     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image "
16557                                                                         "formats must have ONLY the "
16558                                                                         "VK_IMAGE_ASPECT_COLOR_BIT set");
16559
16560     ASSERT_NO_FATAL_FAILURE(InitState());
16561
16562     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16563     VkImageObj image(m_device);
16564     image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
16565     ASSERT_TRUE(image.initialized());
16566
16567     VkImageViewCreateInfo image_view_create_info = {};
16568     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16569     image_view_create_info.image = image.handle();
16570     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16571     image_view_create_info.format = tex_format;
16572     image_view_create_info.subresourceRange.baseMipLevel = 0;
16573     image_view_create_info.subresourceRange.levelCount = 1;
16574     // Cause an error by setting an invalid image aspect
16575     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16576
16577     VkImageView view;
16578     vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16579
16580     m_errorMonitor->VerifyFound();
16581 }
16582
16583 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
16584     VkResult err;
16585     bool pass;
16586
16587     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16588                                          "vkCmdCopyImage: number of layers in source and destination subresources for pRegions");
16589
16590     ASSERT_NO_FATAL_FAILURE(InitState());
16591
16592     // Create two images of different types and try to copy between them
16593     VkImage srcImage;
16594     VkImage dstImage;
16595     VkDeviceMemory srcMem;
16596     VkDeviceMemory destMem;
16597     VkMemoryRequirements memReqs;
16598
16599     VkImageCreateInfo image_create_info = {};
16600     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16601     image_create_info.pNext = NULL;
16602     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16603     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16604     image_create_info.extent.width = 32;
16605     image_create_info.extent.height = 32;
16606     image_create_info.extent.depth = 1;
16607     image_create_info.mipLevels = 1;
16608     image_create_info.arrayLayers = 4;
16609     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16610     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16611     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16612     image_create_info.flags = 0;
16613
16614     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
16615     ASSERT_VK_SUCCESS(err);
16616
16617     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
16618     ASSERT_VK_SUCCESS(err);
16619
16620     // Allocate memory
16621     VkMemoryAllocateInfo memAlloc = {};
16622     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16623     memAlloc.pNext = NULL;
16624     memAlloc.allocationSize = 0;
16625     memAlloc.memoryTypeIndex = 0;
16626
16627     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
16628     memAlloc.allocationSize = memReqs.size;
16629     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16630     ASSERT_TRUE(pass);
16631     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
16632     ASSERT_VK_SUCCESS(err);
16633
16634     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
16635     memAlloc.allocationSize = memReqs.size;
16636     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16637     ASSERT_VK_SUCCESS(err);
16638     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
16639     ASSERT_VK_SUCCESS(err);
16640
16641     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
16642     ASSERT_VK_SUCCESS(err);
16643     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
16644     ASSERT_VK_SUCCESS(err);
16645
16646     BeginCommandBuffer();
16647     VkImageCopy copyRegion;
16648     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16649     copyRegion.srcSubresource.mipLevel = 0;
16650     copyRegion.srcSubresource.baseArrayLayer = 0;
16651     copyRegion.srcSubresource.layerCount = 1;
16652     copyRegion.srcOffset.x = 0;
16653     copyRegion.srcOffset.y = 0;
16654     copyRegion.srcOffset.z = 0;
16655     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16656     copyRegion.dstSubresource.mipLevel = 0;
16657     copyRegion.dstSubresource.baseArrayLayer = 0;
16658     // Introduce failure by forcing the dst layerCount to differ from src
16659     copyRegion.dstSubresource.layerCount = 3;
16660     copyRegion.dstOffset.x = 0;
16661     copyRegion.dstOffset.y = 0;
16662     copyRegion.dstOffset.z = 0;
16663     copyRegion.extent.width = 1;
16664     copyRegion.extent.height = 1;
16665     copyRegion.extent.depth = 1;
16666     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
16667     EndCommandBuffer();
16668
16669     m_errorMonitor->VerifyFound();
16670
16671     vkDestroyImage(m_device->device(), srcImage, NULL);
16672     vkDestroyImage(m_device->device(), dstImage, NULL);
16673     vkFreeMemory(m_device->device(), srcMem, NULL);
16674     vkFreeMemory(m_device->device(), destMem, NULL);
16675 }
16676
16677 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
16678
16679     TEST_DESCRIPTION("Creating images with unsuported formats ");
16680
16681     ASSERT_NO_FATAL_FAILURE(InitState());
16682     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16683     VkImageObj image(m_device);
16684     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16685                VK_IMAGE_TILING_OPTIMAL, 0);
16686     ASSERT_TRUE(image.initialized());
16687
16688     // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
16689     VkImageCreateInfo image_create_info;
16690     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16691     image_create_info.pNext = NULL;
16692     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16693     image_create_info.format = VK_FORMAT_UNDEFINED;
16694     image_create_info.extent.width = 32;
16695     image_create_info.extent.height = 32;
16696     image_create_info.extent.depth = 1;
16697     image_create_info.mipLevels = 1;
16698     image_create_info.arrayLayers = 1;
16699     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16700     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16701     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16702     image_create_info.flags = 0;
16703
16704     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16705                                          "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
16706
16707     VkImage localImage;
16708     vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16709     m_errorMonitor->VerifyFound();
16710
16711     VkFormat unsupported = VK_FORMAT_UNDEFINED;
16712     // Look for a format that is COMPLETELY unsupported with this hardware
16713     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
16714         VkFormat format = static_cast<VkFormat>(f);
16715         VkFormatProperties fProps = m_device->format_properties(format);
16716         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
16717             unsupported = format;
16718             break;
16719         }
16720     }
16721
16722     if (unsupported != VK_FORMAT_UNDEFINED) {
16723         image_create_info.format = unsupported;
16724         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
16725
16726         vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16727         m_errorMonitor->VerifyFound();
16728     }
16729 }
16730
16731 TEST_F(VkLayerTest, ImageLayerViewTests) {
16732     VkResult ret;
16733     TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
16734
16735     ASSERT_NO_FATAL_FAILURE(InitState());
16736
16737     VkImageObj image(m_device);
16738     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16739                VK_IMAGE_TILING_OPTIMAL, 0);
16740     ASSERT_TRUE(image.initialized());
16741
16742     VkImageView imgView;
16743     VkImageViewCreateInfo imgViewInfo = {};
16744     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16745     imgViewInfo.image = image.handle();
16746     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
16747     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16748     imgViewInfo.subresourceRange.layerCount = 1;
16749     imgViewInfo.subresourceRange.baseMipLevel = 0;
16750     imgViewInfo.subresourceRange.levelCount = 1;
16751     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16752
16753     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel");
16754     // View can't have baseMipLevel >= image's mipLevels - Expect
16755     // VIEW_CREATE_ERROR
16756     imgViewInfo.subresourceRange.baseMipLevel = 1;
16757     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16758     m_errorMonitor->VerifyFound();
16759     imgViewInfo.subresourceRange.baseMipLevel = 0;
16760
16761     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer");
16762     // View can't have baseArrayLayer >= image's arraySize - Expect
16763     // VIEW_CREATE_ERROR
16764     imgViewInfo.subresourceRange.baseArrayLayer = 1;
16765     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16766     m_errorMonitor->VerifyFound();
16767     imgViewInfo.subresourceRange.baseArrayLayer = 0;
16768
16769     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16770                                                                         "pCreateInfo->subresourceRange."
16771                                                                         "levelCount");
16772     // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR
16773     imgViewInfo.subresourceRange.levelCount = 0;
16774     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16775     m_errorMonitor->VerifyFound();
16776     imgViewInfo.subresourceRange.levelCount = 1;
16777
16778     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16779                                                                         "pCreateInfo->subresourceRange."
16780                                                                         "layerCount");
16781     // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR
16782     imgViewInfo.subresourceRange.layerCount = 0;
16783     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16784     m_errorMonitor->VerifyFound();
16785     imgViewInfo.subresourceRange.layerCount = 1;
16786
16787     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats");
16788     // Can't use depth format for view into color image - Expect INVALID_FORMAT
16789     imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
16790     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16791     m_errorMonitor->VerifyFound();
16792     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16793
16794     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless "
16795                                                                         "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
16796                                                                         "was set on image creation.");
16797     // Same compatibility class but no MUTABLE_FORMAT bit - Expect
16798     // VIEW_CREATE_ERROR
16799     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
16800     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16801     m_errorMonitor->VerifyFound();
16802     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16803
16804     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with "
16805                                                                         "differing formats but they must be "
16806                                                                         "in the same compatibility class.");
16807     // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect
16808     // VIEW_CREATE_ERROR
16809     VkImageCreateInfo mutImgInfo = image.create_info();
16810     VkImage mutImage;
16811     mutImgInfo.format = VK_FORMAT_R8_UINT;
16812     assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
16813     mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
16814     mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
16815     ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage);
16816     ASSERT_VK_SUCCESS(ret);
16817     imgViewInfo.image = mutImage;
16818     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16819     m_errorMonitor->VerifyFound();
16820     imgViewInfo.image = image.handle();
16821     vkDestroyImage(m_device->handle(), mutImage, NULL);
16822 }
16823
16824 TEST_F(VkLayerTest, MiscImageLayerTests) {
16825
16826     TEST_DESCRIPTION("Image layer tests that don't belong elsewhare");
16827
16828     ASSERT_NO_FATAL_FAILURE(InitState());
16829
16830     VkImageObj image(m_device);
16831     image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16832                VK_IMAGE_TILING_OPTIMAL, 0);
16833     ASSERT_TRUE(image.initialized());
16834
16835     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero");
16836     vk_testing::Buffer buffer;
16837     VkMemoryPropertyFlags reqs = 0;
16838     buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
16839     VkBufferImageCopy region = {};
16840     region.bufferRowLength = 128;
16841     region.bufferImageHeight = 128;
16842     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16843     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
16844     region.imageSubresource.layerCount = 0;
16845     region.imageExtent.height = 4;
16846     region.imageExtent.width = 4;
16847     region.imageExtent.depth = 1;
16848     m_commandBuffer->BeginCommandBuffer();
16849     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16850                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16851     m_errorMonitor->VerifyFound();
16852     region.imageSubresource.layerCount = 1;
16853
16854     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
16855     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
16856     region.bufferOffset = 6;
16857     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size");
16858     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16859                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16860     m_errorMonitor->VerifyFound();
16861
16862     // BufferOffset must be a multiple of 4
16863     // Introduce failure by setting bufferOffset to a value not divisible by 4
16864     region.bufferOffset = 6;
16865     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4");
16866     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16867                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16868     m_errorMonitor->VerifyFound();
16869
16870     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
16871     region.bufferOffset = 0;
16872     region.imageExtent.height = 128;
16873     region.imageExtent.width = 128;
16874     // Introduce failure by setting bufferRowLength > 0 but less than width
16875     region.bufferRowLength = 64;
16876     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16877                                          "must be zero or greater-than-or-equal-to imageExtent.width");
16878     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16879                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16880     m_errorMonitor->VerifyFound();
16881
16882     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
16883     region.bufferRowLength = 128;
16884     // Introduce failure by setting bufferRowHeight > 0 but less than height
16885     region.bufferImageHeight = 64;
16886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16887                                          "must be zero or greater-than-or-equal-to imageExtent.height");
16888     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16889                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16890     m_errorMonitor->VerifyFound();
16891
16892     region.bufferImageHeight = 128;
16893     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must "
16894                                                                         "specify only COLOR or DEPTH or "
16895                                                                         "STENCIL");
16896     // Expect MISMATCHED_IMAGE_ASPECT
16897     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16898     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16899                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
16900     m_errorMonitor->VerifyFound();
16901     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16902
16903     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16904                                          "If the format of srcImage is a depth, stencil, depth stencil or "
16905                                          "integer-based format then filter must be VK_FILTER_NEAREST");
16906     // Expect INVALID_FILTER
16907     VkImageObj intImage1(m_device);
16908     intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16909     VkImageObj intImage2(m_device);
16910     intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16911     VkImageBlit blitRegion = {};
16912     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16913     blitRegion.srcSubresource.baseArrayLayer = 0;
16914     blitRegion.srcSubresource.layerCount = 1;
16915     blitRegion.srcSubresource.mipLevel = 0;
16916     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16917     blitRegion.dstSubresource.baseArrayLayer = 0;
16918     blitRegion.dstSubresource.layerCount = 1;
16919     blitRegion.dstSubresource.mipLevel = 0;
16920
16921     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16922                    intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR);
16923     m_errorMonitor->VerifyFound();
16924
16925     // Look for NULL-blit warning
16926     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area.");
16927     vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16928                    intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR);
16929     m_errorMonitor->VerifyFound();
16930
16931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers");
16932     VkImageMemoryBarrier img_barrier;
16933     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
16934     img_barrier.pNext = NULL;
16935     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
16936     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
16937     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16938     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16939     img_barrier.image = image.handle();
16940     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16941     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16942     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16943     img_barrier.subresourceRange.baseArrayLayer = 0;
16944     img_barrier.subresourceRange.baseMipLevel = 0;
16945     // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE
16946     img_barrier.subresourceRange.layerCount = 0;
16947     img_barrier.subresourceRange.levelCount = 1;
16948     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
16949                          nullptr, 0, nullptr, 1, &img_barrier);
16950     m_errorMonitor->VerifyFound();
16951     img_barrier.subresourceRange.layerCount = 1;
16952 }
16953
16954 TEST_F(VkLayerTest, ImageFormatLimits) {
16955
16956     TEST_DESCRIPTION("Exceed the limits of image format ");
16957
16958     ASSERT_NO_FATAL_FAILURE(InitState());
16959     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16960     VkImageCreateInfo image_create_info = {};
16961     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16962     image_create_info.pNext = NULL;
16963     image_create_info.imageType = VK_IMAGE_TYPE_2D;
16964     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16965     image_create_info.extent.width = 32;
16966     image_create_info.extent.height = 32;
16967     image_create_info.extent.depth = 1;
16968     image_create_info.mipLevels = 1;
16969     image_create_info.arrayLayers = 1;
16970     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16971     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16972     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16973     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
16974     image_create_info.flags = 0;
16975
16976     VkImage nullImg;
16977     VkImageFormatProperties imgFmtProps;
16978     vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
16979                                              image_create_info.usage, image_create_info.flags, &imgFmtProps);
16980     image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1;
16981     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16982     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16983     m_errorMonitor->VerifyFound();
16984     image_create_info.extent.depth = 1;
16985
16986     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16987     image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
16988     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16989     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16990     m_errorMonitor->VerifyFound();
16991     image_create_info.mipLevels = 1;
16992
16993     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16994     image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
16995     // Expect INVALID_FORMAT_LIMITS_VIOLATION
16996     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16997     m_errorMonitor->VerifyFound();
16998     image_create_info.arrayLayers = 1;
16999
17000     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format");
17001     int samples = imgFmtProps.sampleCounts >> 1;
17002     image_create_info.samples = (VkSampleCountFlagBits)samples;
17003     // Expect INVALID_FORMAT_LIMITS_VIOLATION
17004     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17005     m_errorMonitor->VerifyFound();
17006     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17007
17008     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be "
17009                                                                         "VK_IMAGE_LAYOUT_UNDEFINED or "
17010                                                                         "VK_IMAGE_LAYOUT_PREINITIALIZED");
17011     image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
17012     // Expect INVALID_LAYOUT
17013     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17014     m_errorMonitor->VerifyFound();
17015     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17016 }
17017
17018 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
17019     VkResult err;
17020     bool pass;
17021
17022     // Create color images with different format sizes and try to copy between them
17023     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17024                                          "vkCmdCopyImage called with unmatched source and dest image format sizes");
17025
17026     ASSERT_NO_FATAL_FAILURE(InitState());
17027
17028     // Create two images of different types and try to copy between them
17029     VkImage srcImage;
17030     VkImage dstImage;
17031     VkDeviceMemory srcMem;
17032     VkDeviceMemory destMem;
17033     VkMemoryRequirements memReqs;
17034
17035     VkImageCreateInfo image_create_info = {};
17036     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17037     image_create_info.pNext = NULL;
17038     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17039     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17040     image_create_info.extent.width = 32;
17041     image_create_info.extent.height = 32;
17042     image_create_info.extent.depth = 1;
17043     image_create_info.mipLevels = 1;
17044     image_create_info.arrayLayers = 1;
17045     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17046     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17047     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17048     image_create_info.flags = 0;
17049
17050     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17051     ASSERT_VK_SUCCESS(err);
17052
17053     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17054     // Introduce failure by creating second image with a different-sized format.
17055     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
17056
17057     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17058     ASSERT_VK_SUCCESS(err);
17059
17060     // Allocate memory
17061     VkMemoryAllocateInfo memAlloc = {};
17062     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17063     memAlloc.pNext = NULL;
17064     memAlloc.allocationSize = 0;
17065     memAlloc.memoryTypeIndex = 0;
17066
17067     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17068     memAlloc.allocationSize = memReqs.size;
17069     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17070     ASSERT_TRUE(pass);
17071     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17072     ASSERT_VK_SUCCESS(err);
17073
17074     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17075     memAlloc.allocationSize = memReqs.size;
17076     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17077     ASSERT_TRUE(pass);
17078     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17079     ASSERT_VK_SUCCESS(err);
17080
17081     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17082     ASSERT_VK_SUCCESS(err);
17083     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17084     ASSERT_VK_SUCCESS(err);
17085
17086     BeginCommandBuffer();
17087     VkImageCopy copyRegion;
17088     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17089     copyRegion.srcSubresource.mipLevel = 0;
17090     copyRegion.srcSubresource.baseArrayLayer = 0;
17091     copyRegion.srcSubresource.layerCount = 0;
17092     copyRegion.srcOffset.x = 0;
17093     copyRegion.srcOffset.y = 0;
17094     copyRegion.srcOffset.z = 0;
17095     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17096     copyRegion.dstSubresource.mipLevel = 0;
17097     copyRegion.dstSubresource.baseArrayLayer = 0;
17098     copyRegion.dstSubresource.layerCount = 0;
17099     copyRegion.dstOffset.x = 0;
17100     copyRegion.dstOffset.y = 0;
17101     copyRegion.dstOffset.z = 0;
17102     copyRegion.extent.width = 1;
17103     copyRegion.extent.height = 1;
17104     copyRegion.extent.depth = 1;
17105     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17106     EndCommandBuffer();
17107
17108     m_errorMonitor->VerifyFound();
17109
17110     vkDestroyImage(m_device->device(), srcImage, NULL);
17111     vkDestroyImage(m_device->device(), dstImage, NULL);
17112     vkFreeMemory(m_device->device(), srcMem, NULL);
17113     vkFreeMemory(m_device->device(), destMem, NULL);
17114 }
17115
17116 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
17117     VkResult err;
17118     bool pass;
17119
17120     // Create a color image and a depth/stencil image and try to copy between them
17121     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17122                                          "vkCmdCopyImage called with unmatched source and dest image depth");
17123
17124     ASSERT_NO_FATAL_FAILURE(InitState());
17125
17126     // Create two images of different types and try to copy between them
17127     VkImage srcImage;
17128     VkImage dstImage;
17129     VkDeviceMemory srcMem;
17130     VkDeviceMemory destMem;
17131     VkMemoryRequirements memReqs;
17132
17133     VkImageCreateInfo image_create_info = {};
17134     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17135     image_create_info.pNext = NULL;
17136     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17137     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17138     image_create_info.extent.width = 32;
17139     image_create_info.extent.height = 32;
17140     image_create_info.extent.depth = 1;
17141     image_create_info.mipLevels = 1;
17142     image_create_info.arrayLayers = 1;
17143     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17144     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17145     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17146     image_create_info.flags = 0;
17147
17148     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17149     ASSERT_VK_SUCCESS(err);
17150
17151     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17152
17153     // Introduce failure by creating second image with a depth/stencil format
17154     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17155     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17156     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17157
17158     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17159     ASSERT_VK_SUCCESS(err);
17160
17161     // Allocate memory
17162     VkMemoryAllocateInfo memAlloc = {};
17163     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17164     memAlloc.pNext = NULL;
17165     memAlloc.allocationSize = 0;
17166     memAlloc.memoryTypeIndex = 0;
17167
17168     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17169     memAlloc.allocationSize = memReqs.size;
17170     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17171     ASSERT_TRUE(pass);
17172     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17173     ASSERT_VK_SUCCESS(err);
17174
17175     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17176     memAlloc.allocationSize = memReqs.size;
17177     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17178     ASSERT_TRUE(pass);
17179     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17180     ASSERT_VK_SUCCESS(err);
17181
17182     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17183     ASSERT_VK_SUCCESS(err);
17184     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17185     ASSERT_VK_SUCCESS(err);
17186
17187     BeginCommandBuffer();
17188     VkImageCopy copyRegion;
17189     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17190     copyRegion.srcSubresource.mipLevel = 0;
17191     copyRegion.srcSubresource.baseArrayLayer = 0;
17192     copyRegion.srcSubresource.layerCount = 0;
17193     copyRegion.srcOffset.x = 0;
17194     copyRegion.srcOffset.y = 0;
17195     copyRegion.srcOffset.z = 0;
17196     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17197     copyRegion.dstSubresource.mipLevel = 0;
17198     copyRegion.dstSubresource.baseArrayLayer = 0;
17199     copyRegion.dstSubresource.layerCount = 0;
17200     copyRegion.dstOffset.x = 0;
17201     copyRegion.dstOffset.y = 0;
17202     copyRegion.dstOffset.z = 0;
17203     copyRegion.extent.width = 1;
17204     copyRegion.extent.height = 1;
17205     copyRegion.extent.depth = 1;
17206     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
17207     EndCommandBuffer();
17208
17209     m_errorMonitor->VerifyFound();
17210
17211     vkDestroyImage(m_device->device(), srcImage, NULL);
17212     vkDestroyImage(m_device->device(), dstImage, NULL);
17213     vkFreeMemory(m_device->device(), srcMem, NULL);
17214     vkFreeMemory(m_device->device(), destMem, NULL);
17215 }
17216
17217 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
17218     VkResult err;
17219     bool pass;
17220
17221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17222                                          "vkCmdResolveImage called with source sample count less than 2.");
17223
17224     ASSERT_NO_FATAL_FAILURE(InitState());
17225
17226     // Create two images of sample count 1 and try to Resolve between them
17227     VkImage srcImage;
17228     VkImage dstImage;
17229     VkDeviceMemory srcMem;
17230     VkDeviceMemory destMem;
17231     VkMemoryRequirements memReqs;
17232
17233     VkImageCreateInfo image_create_info = {};
17234     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17235     image_create_info.pNext = NULL;
17236     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17237     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17238     image_create_info.extent.width = 32;
17239     image_create_info.extent.height = 1;
17240     image_create_info.extent.depth = 1;
17241     image_create_info.mipLevels = 1;
17242     image_create_info.arrayLayers = 1;
17243     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17244     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17245     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17246     image_create_info.flags = 0;
17247
17248     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17249     ASSERT_VK_SUCCESS(err);
17250
17251     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17252
17253     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17254     ASSERT_VK_SUCCESS(err);
17255
17256     // Allocate memory
17257     VkMemoryAllocateInfo memAlloc = {};
17258     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17259     memAlloc.pNext = NULL;
17260     memAlloc.allocationSize = 0;
17261     memAlloc.memoryTypeIndex = 0;
17262
17263     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17264     memAlloc.allocationSize = memReqs.size;
17265     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17266     ASSERT_TRUE(pass);
17267     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17268     ASSERT_VK_SUCCESS(err);
17269
17270     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17271     memAlloc.allocationSize = memReqs.size;
17272     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17273     ASSERT_TRUE(pass);
17274     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17275     ASSERT_VK_SUCCESS(err);
17276
17277     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17278     ASSERT_VK_SUCCESS(err);
17279     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17280     ASSERT_VK_SUCCESS(err);
17281
17282     BeginCommandBuffer();
17283     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17284     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17285     // VK_IMAGE_LAYOUT_GENERAL = 1,
17286     VkImageResolve resolveRegion;
17287     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17288     resolveRegion.srcSubresource.mipLevel = 0;
17289     resolveRegion.srcSubresource.baseArrayLayer = 0;
17290     resolveRegion.srcSubresource.layerCount = 1;
17291     resolveRegion.srcOffset.x = 0;
17292     resolveRegion.srcOffset.y = 0;
17293     resolveRegion.srcOffset.z = 0;
17294     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17295     resolveRegion.dstSubresource.mipLevel = 0;
17296     resolveRegion.dstSubresource.baseArrayLayer = 0;
17297     resolveRegion.dstSubresource.layerCount = 1;
17298     resolveRegion.dstOffset.x = 0;
17299     resolveRegion.dstOffset.y = 0;
17300     resolveRegion.dstOffset.z = 0;
17301     resolveRegion.extent.width = 1;
17302     resolveRegion.extent.height = 1;
17303     resolveRegion.extent.depth = 1;
17304     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17305     EndCommandBuffer();
17306
17307     m_errorMonitor->VerifyFound();
17308
17309     vkDestroyImage(m_device->device(), srcImage, NULL);
17310     vkDestroyImage(m_device->device(), dstImage, NULL);
17311     vkFreeMemory(m_device->device(), srcMem, NULL);
17312     vkFreeMemory(m_device->device(), destMem, NULL);
17313 }
17314
17315 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
17316     VkResult err;
17317     bool pass;
17318
17319     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17320                                          "vkCmdResolveImage called with dest sample count greater than 1.");
17321
17322     ASSERT_NO_FATAL_FAILURE(InitState());
17323
17324     // Create two images of sample count 4 and try to Resolve between them
17325     VkImage srcImage;
17326     VkImage dstImage;
17327     VkDeviceMemory srcMem;
17328     VkDeviceMemory destMem;
17329     VkMemoryRequirements memReqs;
17330
17331     VkImageCreateInfo image_create_info = {};
17332     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17333     image_create_info.pNext = NULL;
17334     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17335     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17336     image_create_info.extent.width = 32;
17337     image_create_info.extent.height = 1;
17338     image_create_info.extent.depth = 1;
17339     image_create_info.mipLevels = 1;
17340     image_create_info.arrayLayers = 1;
17341     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
17342     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17343     // Note: Some implementations expect color attachment usage for any
17344     // multisample surface
17345     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17346     image_create_info.flags = 0;
17347
17348     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17349     ASSERT_VK_SUCCESS(err);
17350
17351     // Note: Some implementations expect color attachment usage for any
17352     // multisample surface
17353     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17354
17355     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17356     ASSERT_VK_SUCCESS(err);
17357
17358     // Allocate memory
17359     VkMemoryAllocateInfo memAlloc = {};
17360     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17361     memAlloc.pNext = NULL;
17362     memAlloc.allocationSize = 0;
17363     memAlloc.memoryTypeIndex = 0;
17364
17365     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17366     memAlloc.allocationSize = memReqs.size;
17367     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17368     ASSERT_TRUE(pass);
17369     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17370     ASSERT_VK_SUCCESS(err);
17371
17372     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17373     memAlloc.allocationSize = memReqs.size;
17374     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17375     ASSERT_TRUE(pass);
17376     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17377     ASSERT_VK_SUCCESS(err);
17378
17379     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17380     ASSERT_VK_SUCCESS(err);
17381     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17382     ASSERT_VK_SUCCESS(err);
17383
17384     BeginCommandBuffer();
17385     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17386     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17387     // VK_IMAGE_LAYOUT_GENERAL = 1,
17388     VkImageResolve resolveRegion;
17389     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17390     resolveRegion.srcSubresource.mipLevel = 0;
17391     resolveRegion.srcSubresource.baseArrayLayer = 0;
17392     resolveRegion.srcSubresource.layerCount = 1;
17393     resolveRegion.srcOffset.x = 0;
17394     resolveRegion.srcOffset.y = 0;
17395     resolveRegion.srcOffset.z = 0;
17396     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17397     resolveRegion.dstSubresource.mipLevel = 0;
17398     resolveRegion.dstSubresource.baseArrayLayer = 0;
17399     resolveRegion.dstSubresource.layerCount = 1;
17400     resolveRegion.dstOffset.x = 0;
17401     resolveRegion.dstOffset.y = 0;
17402     resolveRegion.dstOffset.z = 0;
17403     resolveRegion.extent.width = 1;
17404     resolveRegion.extent.height = 1;
17405     resolveRegion.extent.depth = 1;
17406     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17407     EndCommandBuffer();
17408
17409     m_errorMonitor->VerifyFound();
17410
17411     vkDestroyImage(m_device->device(), srcImage, NULL);
17412     vkDestroyImage(m_device->device(), dstImage, NULL);
17413     vkFreeMemory(m_device->device(), srcMem, NULL);
17414     vkFreeMemory(m_device->device(), destMem, NULL);
17415 }
17416
17417 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
17418     VkResult err;
17419     bool pass;
17420
17421     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17422                                          "vkCmdResolveImage called with unmatched source and dest formats.");
17423
17424     ASSERT_NO_FATAL_FAILURE(InitState());
17425
17426     // Create two images of different types and try to copy between them
17427     VkImage srcImage;
17428     VkImage dstImage;
17429     VkDeviceMemory srcMem;
17430     VkDeviceMemory destMem;
17431     VkMemoryRequirements memReqs;
17432
17433     VkImageCreateInfo image_create_info = {};
17434     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17435     image_create_info.pNext = NULL;
17436     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17437     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17438     image_create_info.extent.width = 32;
17439     image_create_info.extent.height = 1;
17440     image_create_info.extent.depth = 1;
17441     image_create_info.mipLevels = 1;
17442     image_create_info.arrayLayers = 1;
17443     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17444     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17445     // Note: Some implementations expect color attachment usage for any
17446     // multisample surface
17447     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17448     image_create_info.flags = 0;
17449
17450     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17451     ASSERT_VK_SUCCESS(err);
17452
17453     // Set format to something other than source image
17454     image_create_info.format = VK_FORMAT_R32_SFLOAT;
17455     // Note: Some implementations expect color attachment usage for any
17456     // multisample surface
17457     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17458     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17459
17460     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17461     ASSERT_VK_SUCCESS(err);
17462
17463     // Allocate memory
17464     VkMemoryAllocateInfo memAlloc = {};
17465     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17466     memAlloc.pNext = NULL;
17467     memAlloc.allocationSize = 0;
17468     memAlloc.memoryTypeIndex = 0;
17469
17470     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17471     memAlloc.allocationSize = memReqs.size;
17472     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17473     ASSERT_TRUE(pass);
17474     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17475     ASSERT_VK_SUCCESS(err);
17476
17477     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17478     memAlloc.allocationSize = memReqs.size;
17479     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17480     ASSERT_TRUE(pass);
17481     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17482     ASSERT_VK_SUCCESS(err);
17483
17484     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17485     ASSERT_VK_SUCCESS(err);
17486     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17487     ASSERT_VK_SUCCESS(err);
17488
17489     BeginCommandBuffer();
17490     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17491     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17492     // VK_IMAGE_LAYOUT_GENERAL = 1,
17493     VkImageResolve resolveRegion;
17494     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17495     resolveRegion.srcSubresource.mipLevel = 0;
17496     resolveRegion.srcSubresource.baseArrayLayer = 0;
17497     resolveRegion.srcSubresource.layerCount = 1;
17498     resolveRegion.srcOffset.x = 0;
17499     resolveRegion.srcOffset.y = 0;
17500     resolveRegion.srcOffset.z = 0;
17501     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17502     resolveRegion.dstSubresource.mipLevel = 0;
17503     resolveRegion.dstSubresource.baseArrayLayer = 0;
17504     resolveRegion.dstSubresource.layerCount = 1;
17505     resolveRegion.dstOffset.x = 0;
17506     resolveRegion.dstOffset.y = 0;
17507     resolveRegion.dstOffset.z = 0;
17508     resolveRegion.extent.width = 1;
17509     resolveRegion.extent.height = 1;
17510     resolveRegion.extent.depth = 1;
17511     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17512     EndCommandBuffer();
17513
17514     m_errorMonitor->VerifyFound();
17515
17516     vkDestroyImage(m_device->device(), srcImage, NULL);
17517     vkDestroyImage(m_device->device(), dstImage, NULL);
17518     vkFreeMemory(m_device->device(), srcMem, NULL);
17519     vkFreeMemory(m_device->device(), destMem, NULL);
17520 }
17521
17522 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
17523     VkResult err;
17524     bool pass;
17525
17526     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17527                                          "vkCmdResolveImage called with unmatched source and dest image types.");
17528
17529     ASSERT_NO_FATAL_FAILURE(InitState());
17530
17531     // Create two images of different types and try to copy between them
17532     VkImage srcImage;
17533     VkImage dstImage;
17534     VkDeviceMemory srcMem;
17535     VkDeviceMemory destMem;
17536     VkMemoryRequirements memReqs;
17537
17538     VkImageCreateInfo image_create_info = {};
17539     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17540     image_create_info.pNext = NULL;
17541     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17542     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17543     image_create_info.extent.width = 32;
17544     image_create_info.extent.height = 1;
17545     image_create_info.extent.depth = 1;
17546     image_create_info.mipLevels = 1;
17547     image_create_info.arrayLayers = 1;
17548     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17549     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17550     // Note: Some implementations expect color attachment usage for any
17551     // multisample surface
17552     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17553     image_create_info.flags = 0;
17554
17555     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17556     ASSERT_VK_SUCCESS(err);
17557
17558     image_create_info.imageType = VK_IMAGE_TYPE_1D;
17559     // Note: Some implementations expect color attachment usage for any
17560     // multisample surface
17561     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17562     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17563
17564     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17565     ASSERT_VK_SUCCESS(err);
17566
17567     // Allocate memory
17568     VkMemoryAllocateInfo memAlloc = {};
17569     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17570     memAlloc.pNext = NULL;
17571     memAlloc.allocationSize = 0;
17572     memAlloc.memoryTypeIndex = 0;
17573
17574     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17575     memAlloc.allocationSize = memReqs.size;
17576     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17577     ASSERT_TRUE(pass);
17578     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17579     ASSERT_VK_SUCCESS(err);
17580
17581     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17582     memAlloc.allocationSize = memReqs.size;
17583     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17584     ASSERT_TRUE(pass);
17585     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17586     ASSERT_VK_SUCCESS(err);
17587
17588     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17589     ASSERT_VK_SUCCESS(err);
17590     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17591     ASSERT_VK_SUCCESS(err);
17592
17593     BeginCommandBuffer();
17594     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17595     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17596     // VK_IMAGE_LAYOUT_GENERAL = 1,
17597     VkImageResolve resolveRegion;
17598     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17599     resolveRegion.srcSubresource.mipLevel = 0;
17600     resolveRegion.srcSubresource.baseArrayLayer = 0;
17601     resolveRegion.srcSubresource.layerCount = 1;
17602     resolveRegion.srcOffset.x = 0;
17603     resolveRegion.srcOffset.y = 0;
17604     resolveRegion.srcOffset.z = 0;
17605     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17606     resolveRegion.dstSubresource.mipLevel = 0;
17607     resolveRegion.dstSubresource.baseArrayLayer = 0;
17608     resolveRegion.dstSubresource.layerCount = 1;
17609     resolveRegion.dstOffset.x = 0;
17610     resolveRegion.dstOffset.y = 0;
17611     resolveRegion.dstOffset.z = 0;
17612     resolveRegion.extent.width = 1;
17613     resolveRegion.extent.height = 1;
17614     resolveRegion.extent.depth = 1;
17615     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17616     EndCommandBuffer();
17617
17618     m_errorMonitor->VerifyFound();
17619
17620     vkDestroyImage(m_device->device(), srcImage, NULL);
17621     vkDestroyImage(m_device->device(), dstImage, NULL);
17622     vkFreeMemory(m_device->device(), srcMem, NULL);
17623     vkFreeMemory(m_device->device(), destMem, NULL);
17624 }
17625
17626 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
17627     // Create a single Image descriptor and cause it to first hit an error due
17628     //  to using a DS format, then cause it to hit error due to COLOR_BIT not
17629     //  set in aspect
17630     // The image format check comes 2nd in validation so we trigger it first,
17631     //  then when we cause aspect fail next, bad format check will be preempted
17632     VkResult err;
17633
17634     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17635                                          "Combination depth/stencil image formats can have only the ");
17636
17637     ASSERT_NO_FATAL_FAILURE(InitState());
17638
17639     VkDescriptorPoolSize ds_type_count = {};
17640     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17641     ds_type_count.descriptorCount = 1;
17642
17643     VkDescriptorPoolCreateInfo ds_pool_ci = {};
17644     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
17645     ds_pool_ci.pNext = NULL;
17646     ds_pool_ci.maxSets = 1;
17647     ds_pool_ci.poolSizeCount = 1;
17648     ds_pool_ci.pPoolSizes = &ds_type_count;
17649
17650     VkDescriptorPool ds_pool;
17651     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
17652     ASSERT_VK_SUCCESS(err);
17653
17654     VkDescriptorSetLayoutBinding dsl_binding = {};
17655     dsl_binding.binding = 0;
17656     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17657     dsl_binding.descriptorCount = 1;
17658     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
17659     dsl_binding.pImmutableSamplers = NULL;
17660
17661     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
17662     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
17663     ds_layout_ci.pNext = NULL;
17664     ds_layout_ci.bindingCount = 1;
17665     ds_layout_ci.pBindings = &dsl_binding;
17666     VkDescriptorSetLayout ds_layout;
17667     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
17668     ASSERT_VK_SUCCESS(err);
17669
17670     VkDescriptorSet descriptorSet;
17671     VkDescriptorSetAllocateInfo alloc_info = {};
17672     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
17673     alloc_info.descriptorSetCount = 1;
17674     alloc_info.descriptorPool = ds_pool;
17675     alloc_info.pSetLayouts = &ds_layout;
17676     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
17677     ASSERT_VK_SUCCESS(err);
17678
17679     VkImage image_bad;
17680     VkImage image_good;
17681     // One bad format and one good format for Color attachment
17682     const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
17683     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
17684     const int32_t tex_width = 32;
17685     const int32_t tex_height = 32;
17686
17687     VkImageCreateInfo image_create_info = {};
17688     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17689     image_create_info.pNext = NULL;
17690     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17691     image_create_info.format = tex_format_bad;
17692     image_create_info.extent.width = tex_width;
17693     image_create_info.extent.height = tex_height;
17694     image_create_info.extent.depth = 1;
17695     image_create_info.mipLevels = 1;
17696     image_create_info.arrayLayers = 1;
17697     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17698     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17699     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17700     image_create_info.flags = 0;
17701
17702     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
17703     ASSERT_VK_SUCCESS(err);
17704     image_create_info.format = tex_format_good;
17705     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17706     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
17707     ASSERT_VK_SUCCESS(err);
17708
17709     VkImageViewCreateInfo image_view_create_info = {};
17710     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17711     image_view_create_info.image = image_bad;
17712     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
17713     image_view_create_info.format = tex_format_bad;
17714     image_view_create_info.subresourceRange.baseArrayLayer = 0;
17715     image_view_create_info.subresourceRange.baseMipLevel = 0;
17716     image_view_create_info.subresourceRange.layerCount = 1;
17717     image_view_create_info.subresourceRange.levelCount = 1;
17718     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17719
17720     VkImageView view;
17721     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
17722
17723     m_errorMonitor->VerifyFound();
17724
17725     vkDestroyImage(m_device->device(), image_bad, NULL);
17726     vkDestroyImage(m_device->device(), image_good, NULL);
17727     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
17728     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
17729 }
17730
17731 TEST_F(VkLayerTest, ClearImageErrors) {
17732     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and "
17733                      "ClearDepthStencilImage with a color image.");
17734
17735     ASSERT_NO_FATAL_FAILURE(InitState());
17736     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17737
17738     // Renderpass is started here so end it as Clear cmds can't be in renderpass
17739     BeginCommandBuffer();
17740     m_commandBuffer->EndRenderPass();
17741
17742     // Color image
17743     VkClearColorValue clear_color;
17744     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
17745     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
17746     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
17747     const int32_t img_width = 32;
17748     const int32_t img_height = 32;
17749     VkImageCreateInfo image_create_info = {};
17750     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17751     image_create_info.pNext = NULL;
17752     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17753     image_create_info.format = color_format;
17754     image_create_info.extent.width = img_width;
17755     image_create_info.extent.height = img_height;
17756     image_create_info.extent.depth = 1;
17757     image_create_info.mipLevels = 1;
17758     image_create_info.arrayLayers = 1;
17759     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17760     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17761     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
17762
17763     vk_testing::Image color_image;
17764     color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
17765
17766     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
17767
17768     // Depth/Stencil image
17769     VkClearDepthStencilValue clear_value = {0};
17770     reqs = 0; // don't need HOST_VISIBLE DS image
17771     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
17772     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
17773     ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17774     ds_image_create_info.extent.width = 64;
17775     ds_image_create_info.extent.height = 64;
17776     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17777     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17778
17779     vk_testing::Image ds_image;
17780     ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs);
17781
17782     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
17783
17784     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
17785
17786     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17787                          &color_range);
17788
17789     m_errorMonitor->VerifyFound();
17790
17791     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with "
17792                                                                         "image created without "
17793                                                                         "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
17794
17795     vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17796                          &color_range);
17797
17798     m_errorMonitor->VerifyFound();
17799
17800     // Call CmdClearDepthStencilImage with color image
17801     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17802                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
17803
17804     vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(),
17805                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range);
17806
17807     m_errorMonitor->VerifyFound();
17808 }
17809 #endif // IMAGE_TESTS
17810
17811 #if defined(ANDROID) && defined(VALIDATION_APK)
17812 static bool initialized = false;
17813 static bool active = false;
17814
17815 // Convert Intents to argv
17816 // Ported from Hologram sample, only difference is flexible key
17817 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
17818     std::vector<std::string> args;
17819     JavaVM &vm = *app.activity->vm;
17820     JNIEnv *p_env;
17821     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
17822         return args;
17823
17824     JNIEnv &env = *p_env;
17825     jobject activity = app.activity->clazz;
17826     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
17827     jobject intent = env.CallObjectMethod(activity, get_intent_method);
17828     jmethodID get_string_extra_method =
17829         env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
17830     jvalue get_string_extra_args;
17831     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
17832     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
17833
17834     std::string args_str;
17835     if (extra_str) {
17836         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
17837         args_str = extra_utf;
17838         env.ReleaseStringUTFChars(extra_str, extra_utf);
17839         env.DeleteLocalRef(extra_str);
17840     }
17841
17842     env.DeleteLocalRef(get_string_extra_args.l);
17843     env.DeleteLocalRef(intent);
17844     vm.DetachCurrentThread();
17845
17846     // split args_str
17847     std::stringstream ss(args_str);
17848     std::string arg;
17849     while (std::getline(ss, arg, ' ')) {
17850         if (!arg.empty())
17851             args.push_back(arg);
17852     }
17853
17854     return args;
17855 }
17856
17857 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
17858
17859 static void processCommand(struct android_app *app, int32_t cmd) {
17860     switch (cmd) {
17861     case APP_CMD_INIT_WINDOW: {
17862         if (app->window) {
17863             initialized = true;
17864         }
17865         break;
17866     }
17867     case APP_CMD_GAINED_FOCUS: {
17868         active = true;
17869         break;
17870     }
17871     case APP_CMD_LOST_FOCUS: {
17872         active = false;
17873         break;
17874     }
17875     }
17876 }
17877
17878 void android_main(struct android_app *app) {
17879     app_dummy();
17880
17881     const char *appTag = "VulkanLayerValidationTests";
17882
17883     int vulkanSupport = InitVulkan();
17884     if (vulkanSupport == 0) {
17885         __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
17886         return;
17887     }
17888
17889     app->onAppCmd = processCommand;
17890     app->onInputEvent = processInput;
17891
17892     while (1) {
17893         int events;
17894         struct android_poll_source *source;
17895         while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
17896             if (source) {
17897                 source->process(app, source);
17898             }
17899
17900             if (app->destroyRequested != 0) {
17901                 VkTestFramework::Finish();
17902                 return;
17903             }
17904         }
17905
17906         if (initialized && active) {
17907             // Use the following key to send arguments to gtest, i.e.
17908             // --es args "--gtest_filter=-VkLayerTest.foo"
17909             const char key[] = "args";
17910             std::vector<std::string> args = get_args(*app, key);
17911
17912             std::string filter = "";
17913             if (args.size() > 0) {
17914                 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
17915                 filter += args[0];
17916             } else {
17917                 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
17918             }
17919
17920             int argc = 2;
17921             char *argv[] = {(char *)"foo", (char *)filter.c_str()};
17922             __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
17923
17924             // Route output to files until we can override the gtest output
17925             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
17926             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
17927
17928             ::testing::InitGoogleTest(&argc, argv);
17929             VkTestFramework::InitArgs(&argc, argv);
17930             ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17931
17932             int result = RUN_ALL_TESTS();
17933
17934             if (result != 0) {
17935                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
17936             } else {
17937                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
17938             }
17939
17940             VkTestFramework::Finish();
17941
17942             fclose(stdout);
17943             fclose(stderr);
17944
17945             ANativeActivity_finish(app->activity);
17946
17947             return;
17948         }
17949     }
17950 }
17951 #endif
17952
17953 int main(int argc, char **argv) {
17954     int result;
17955
17956 #ifdef ANDROID
17957     int vulkanSupport = InitVulkan();
17958     if (vulkanSupport == 0)
17959         return 1;
17960 #endif
17961
17962     ::testing::InitGoogleTest(&argc, argv);
17963     VkTestFramework::InitArgs(&argc, argv);
17964
17965     ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17966
17967     result = RUN_ALL_TESTS();
17968
17969     VkTestFramework::Finish();
17970     return result;
17971 }