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.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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>
24 #include "vulkan_wrapper.h"
26 #include <vulkan/vulkan.h>
29 #if defined(ANDROID) && defined(VALIDATION_APK)
30 #include <android/log.h>
31 #include <android_native_app_glue.h>
35 #include "test_common.h"
36 #include "vk_layer_config.h"
37 #include "vkrenderframework.h"
38 #include <unordered_set>
40 #define GLM_FORCE_RADIANS
41 #include "glm/glm.hpp"
42 #include <glm/gtc/matrix_transform.hpp>
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
53 //--------------------------------------------------------------------------------------
54 // Mesh and VertexFormat Data
55 //--------------------------------------------------------------------------------------
57 float posX, posY, posZ, posW; // Position data
58 float r, g, b, a; // Color
61 #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
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,
78 struct vktriangle_vs_uniform {
79 // Must start with MVP
85 static const char bindStateVertShaderText[] = "#version 450\n"
87 "out gl_PerVertex {\n"
88 " vec4 gl_Position;\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"
97 static const char bindStateFragShaderText[] = "#version 450\n"
99 "layout(location = 0) out vec4 uFragColor;\n"
101 " uFragColor = vec4(0,1,0,1);\n"
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,
108 // ********************************************************
109 // ErrorMonitor Usage:
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.
115 // Call DesiredMsgFound to determine if the desired failure message
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;
125 m_desiredMsgSet = false;
126 test_platform_thread_unlock_mutex(&m_mutex);
129 ~ErrorMonitor() { test_platform_thread_delete_mutex(&m_mutex); }
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();
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);
143 VkBool32 CheckForDesiredMsg(const char *msgString) {
144 VkBool32 result = VK_FALSE;
145 test_platform_thread_lock_mutex(&m_mutex);
146 if (m_bailout != NULL) {
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;
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);
163 if (!found_expected) {
164 printf("Unexpected: %s\n", msgString);
165 m_otherMsgs.push_back(errorString);
167 test_platform_thread_unlock_mutex(&m_mutex);
171 vector<string> GetOtherFailureMsgs(void) { return m_otherMsgs; }
173 VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; }
175 VkBool32 DesiredMsgFound(void) { return m_msgFound; }
177 void SetBailout(bool *bailout) { m_bailout = bailout; }
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;
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, "");
197 // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages.
198 if (!DesiredMsgFound()) {
200 for (auto desired_msg : m_desiredMsgs) {
201 FAIL() << "Did not receive expected error '" << desired_msg << "'";
206 void VerifyNotFound() {
207 // ExpectSuccess() configured us to match anything. Any error is a failure.
208 if (DesiredMsgFound()) {
210 for (auto msg : m_failureMsgs) {
211 FAIL() << "Expected to succeed but got error: " << msg;
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;
224 bool m_desiredMsgSet;
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,
230 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
231 if (msgFlags & errMonitor->GetMessageFlags()) {
232 return errMonitor->CheckForDesiredMsg(pMsg);
237 class VkLayerTest : public VkRenderFramework {
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);
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);
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);
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);
263 void BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset) {
264 m_commandBuffer->BindIndexBuffer(indexBuffer, offset);
268 ErrorMonitor *m_errorMonitor;
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;
276 instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
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.
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");
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
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;
324 m_errorMonitor = new ErrorMonitor;
325 InitFramework(instance_layer_names, instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
328 virtual void TearDown() {
329 // Clean up resources before we reset
331 delete m_errorMonitor;
334 VkLayerTest() { m_enableWSI = false; }
337 VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &commandBuffer) {
340 result = commandBuffer.BeginCommandBuffer();
343 * For render test all drawing happens in a single render pass
344 * on a single command buffer.
346 if (VK_SUCCESS == result && renderPass()) {
347 commandBuffer.BeginRenderPass(renderPassBeginInfo());
353 VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &commandBuffer) {
357 commandBuffer.EndRenderPass();
360 result = commandBuffer.EndCommandBuffer();
365 void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask) {
366 // Create identity matrix
368 struct vktriangle_vs_uniform data;
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);
377 memcpy(&data.mvp, &MVP[0][0], matrixSize);
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)},
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;
394 ASSERT_NO_FATAL_FAILURE(InitViewport());
396 VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data,
397 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
399 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
400 VkShaderObj ps(m_device, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
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);
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);
421 // Viewport and scissors must stay in synch or other errors will occur than
423 if (failMask & BsoFailViewport) {
424 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
426 if (failMask & BsoFailScissor) {
427 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
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);
436 if (failMask & BsoFailDepthBounds) {
437 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
439 if (failMask & BsoFailStencilReadMask) {
440 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
442 if (failMask & BsoFailStencilWriteMask) {
443 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
445 if (failMask & BsoFailStencilReference) {
446 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
449 VkDescriptorSetObj descriptorSet(m_device);
450 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
452 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
453 ASSERT_VK_SUCCESS(BeginCommandBuffer());
455 GenericDrawPreparation(pipelineobj, descriptorSet, failMask);
458 if (failMask & BsoFailIndexBuffer) {
459 // Use DrawIndexed w/o an index buffer bound
460 DrawIndexed(3, 1, 0, 0, 0);
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};
471 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
474 // finalize recording of the command buffer
477 QueueCommandBuffer();
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);
485 commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
488 commandBuffer->PrepareAttachments();
489 // Make sure depthWriteEnable is set so that Depth fail test will work
491 // Make sure stencilTestEnable is set so that Stencil fail test will work
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;
499 VkPipelineDepthStencilStateCreateInfo ds_ci = {};
500 ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
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;
511 ds_ci.stencilTestEnable = VK_TRUE;
512 ds_ci.front = stencil;
513 ds_ci.back = stencil;
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);
525 class VkWsiEnabledLayerTest : public VkLayerTest {
528 VkWsiEnabledLayerTest() { m_enableWSI = true; }
535 eInvalidDeviceOffset,
536 eInvalidMemoryOffset,
542 enum eTestConditions { eOffsetAlignment = 1 };
544 static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) {
545 if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) {
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;
556 vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer);
557 VkMemoryRequirements memory_reqs = {};
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;
569 if (eOffsetAlignment < offset_limit) {
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()) {
579 if (eBindNullBuffer == aTestFlag) {
581 vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
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;
588 vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer);
590 CreateCurrent = true;
592 VkMemoryRequirements memory_requirements;
593 vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements);
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);
601 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
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);
612 InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
618 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
620 if (AllocateCurrent) {
621 if (InvalidDeleteEn) {
623 VkDeviceMemory device_memory;
624 unsigned long long index_access;
627 bad_index.device_memory = VulkanMemory;
628 bad_index.index_access++;
630 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr);
632 vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
636 bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; }
638 const VkBuffer &GetBuffer() { return VulkanBuffer; }
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);
647 bool AllocateCurrent;
650 bool InvalidDeleteEn;
652 VkBuffer VulkanBuffer;
653 VkDevice VulkanDevice;
654 VkDeviceMemory VulkanMemory;
657 class VkVerticesObj {
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
667 VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount];
668 VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount];
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;
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;
683 } while (AttributeCount < i);
687 VertexInputBindingDescription[i].binding = BindId;
688 VertexInputBindingDescription[i].stride = aByteStride;
689 VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
691 } while (BindingCount < i);
695 if (VertexInputAttributeDescription) {
696 delete[] VertexInputAttributeDescription;
698 if (VertexInputBindingDescription) {
699 delete[] VertexInputBindingDescription;
703 bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
704 aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount);
705 aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount);
709 void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) {
710 VkDeviceSize *offsetList;
711 unsigned offsetCount;
714 offsetList = aOffsetList;
715 offsetCount = aOffsetCount;
717 offsetList = new VkDeviceSize[1]();
721 vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList);
730 static uint32_t BindIdGenerator;
733 unsigned AttributeCount;
734 unsigned BindingCount;
737 VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
738 VkVertexInputAttributeDescription *VertexInputAttributeDescription;
739 VkVertexInputBindingDescription *VertexInputBindingDescription;
740 VkConstantBufferObj VulkanMemoryBuffer;
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");
753 ASSERT_NO_FATAL_FAILURE(InitState());
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();
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();
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();
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();
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();
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();
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();
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();
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();
827 TEST_F(VkLayerTest, ReservedParameter) {
828 TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
830 ASSERT_NO_FATAL_FAILURE(InitState());
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();
844 TEST_F(VkLayerTest, InvalidStructSType) {
845 TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan "
846 "structure's sType field");
848 ASSERT_NO_FATAL_FAILURE(InitState());
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();
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();
870 TEST_F(VkLayerTest, InvalidStructPNext) {
871 TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
873 ASSERT_NO_FATAL_FAILURE(InitState());
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
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();
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();
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);
911 if (extension_count > 0) {
912 std::vector<VkExtensionProperties> available_extensions(extension_count);
914 err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]);
915 ASSERT_VK_SUCCESS(err);
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;
924 if (supports_nv_dedicated_allocation) {
925 m_errorMonitor->ExpectSuccess();
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;
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;
942 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
943 ASSERT_VK_SUCCESS(err);
945 VkMemoryRequirements memory_reqs;
946 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
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;
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;
960 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
963 VkDeviceMemory buffer_memory;
964 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
965 ASSERT_VK_SUCCESS(err);
967 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
968 ASSERT_VK_SUCCESS(err);
970 vkDestroyBuffer(m_device->device(), buffer, NULL);
971 vkFreeMemory(m_device->device(), buffer_memory, NULL);
973 m_errorMonitor->VerifyNotFound();
977 TEST_F(VkLayerTest, UnrecognizedValue) {
978 TEST_DESCRIPTION("Specify unrecognized Vulkan enumeration, flags, and VkBool32 values");
980 ASSERT_NO_FATAL_FAILURE(InitState());
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();
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();
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();
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();
1042 TEST_F(VkLayerTest, FailedReturnValue) {
1043 TEST_DESCRIPTION("Check for a message describing a VkResult failure code");
1045 ASSERT_NO_FATAL_FAILURE(InitState());
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;
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();
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};
1077 ASSERT_NO_FATAL_FAILURE(InitState());
1079 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1080 vk_testing::Buffer buffer;
1081 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
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();
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();
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();
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();
1109 TEST_F(VkLayerTest, FillBufferAlignment) {
1110 TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
1112 ASSERT_NO_FATAL_FAILURE(InitState());
1114 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1115 vk_testing::Buffer buffer;
1116 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1118 BeginCommandBuffer();
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();
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();
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();
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.");
1147 const uintptr_t invalid_ptr = 0xcdcdcdcd;
1149 ASSERT_NO_FATAL_FAILURE(InitState());
1153 m_errorMonitor->ExpectSuccess();
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);
1176 VkMemoryRequirements memory_reqs;
1177 VkDeviceMemory image_memory;
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);
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);
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;
1204 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
1205 ASSERT_VK_SUCCESS(err);
1207 VkDescriptorPoolSize ds_type_count = {};
1208 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1209 ds_type_count.descriptorCount = 1;
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;
1218 VkDescriptorPool ds_pool;
1219 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1220 ASSERT_VK_SUCCESS(err);
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;
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);
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);
1247 VkDescriptorImageInfo image_info = {};
1248 image_info.imageView = view;
1249 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
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;
1260 // Set pBufferInfo and pTexelBufferView to invalid values, which should
1262 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
1263 // This will most likely produce a crash if the parameter_validation
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);
1269 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1271 m_errorMonitor->VerifyNotFound();
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);
1282 m_errorMonitor->ExpectSuccess();
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;
1293 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1294 ASSERT_VK_SUCCESS(err);
1296 VkMemoryRequirements memory_reqs;
1297 VkDeviceMemory buffer_memory;
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;
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);
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);
1315 VkDescriptorPoolSize ds_type_count = {};
1316 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1317 ds_type_count.descriptorCount = 1;
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;
1326 VkDescriptorPool ds_pool;
1327 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1328 ASSERT_VK_SUCCESS(err);
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;
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);
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);
1355 VkDescriptorBufferInfo buffer_info = {};
1356 buffer_info.buffer = buffer;
1357 buffer_info.offset = 0;
1358 buffer_info.range = 1024;
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;
1369 // Set pImageInfo and pTexelBufferView to invalid values, which should
1371 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
1372 // This will most likely produce a crash if the parameter_validation
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);
1378 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1380 m_errorMonitor->VerifyNotFound();
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);
1389 // Texel Buffer Case
1391 m_errorMonitor->ExpectSuccess();
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;
1402 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
1403 ASSERT_VK_SUCCESS(err);
1405 VkMemoryRequirements memory_reqs;
1406 VkDeviceMemory buffer_memory;
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;
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);
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);
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);
1432 VkDescriptorPoolSize ds_type_count = {};
1433 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1434 ds_type_count.descriptorCount = 1;
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;
1443 VkDescriptorPool ds_pool;
1444 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
1445 ASSERT_VK_SUCCESS(err);
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;
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);
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);
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;
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
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);
1490 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1492 m_errorMonitor->VerifyNotFound();
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);
1503 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
1506 TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a "
1507 "pipeline when this feature is not enabled.");
1509 ASSERT_NO_FATAL_FAILURE(InitState());
1510 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
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);
1519 VkRenderpassObj render_pass(&test_device);
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;
1526 VkPipelineLayout pipeline_layout;
1527 err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout);
1528 ASSERT_VK_SUCCESS(err);
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;
1536 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1537 VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
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");
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());
1552 m_errorMonitor->VerifyFound();
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");
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());
1567 m_errorMonitor->VerifyFound();
1569 // Try again with polygonMode=FILL. No error is expected
1570 m_errorMonitor->ExpectSuccess();
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());
1581 m_errorMonitor->VerifyNotFound();
1583 vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL);
1586 #endif // PARAMETER_VALIDATION_TESTS
1588 #if MEM_TRACKER_TESTS
1590 TEST_F(VkLayerTest, CallResetCommandBufferBeforeCompletion)
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;
1598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting CB");
1600 ASSERT_NO_FATAL_FAILURE(InitState());
1602 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1603 vk_testing::Buffer buffer;
1604 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
1606 BeginCommandBuffer();
1607 m_commandBuffer->FillBuffer(buffer.handle(), 0, 4, 0x11111111);
1610 testFence.init(*m_device, fenceInfo);
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;
1625 err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1626 ASSERT_VK_SUCCESS( err );
1628 // Introduce failure by calling begin again before checking fence
1629 vkResetCommandBuffer(m_commandBuffer->handle(), 0);
1631 m_errorMonitor->VerifyFound();
1634 TEST_F(VkLayerTest, CallBeginCommandBufferBeforeCompletion)
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;
1642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active CB");
1644 ASSERT_NO_FATAL_FAILURE(InitState());
1645 ASSERT_NO_FATAL_FAILURE(InitViewport());
1646 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1648 BeginCommandBuffer();
1649 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
1652 testFence.init(*m_device, fenceInfo);
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;
1667 err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle());
1668 ASSERT_VK_SUCCESS( err );
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;
1676 info.framebuffer = VK_NULL_HANDLE;
1677 info.occlusionQueryEnable = VK_FALSE;
1678 info.queryFlags = 0;
1679 info.pipelineStatistics = 0;
1681 // Introduce failure by calling BCB again before checking fence
1682 vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
1684 m_errorMonitor->VerifyFound();
1688 // This is a positive test. No failures are expected.
1689 TEST_F(VkLayerTest, TestAliasedMemoryTracking) {
1693 TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
1694 "the buffer, create an image, and bind the same memory to "
1697 m_errorMonitor->ExpectSuccess();
1699 ASSERT_NO_FATAL_FAILURE(InitState());
1704 VkMemoryRequirements mem_reqs;
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;
1715 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1716 ASSERT_VK_SUCCESS(err);
1718 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
1720 VkMemoryAllocateInfo alloc_info = {};
1721 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1722 alloc_info.pNext = NULL;
1723 alloc_info.memoryTypeIndex = 0;
1725 // Ensure memory is big enough for both bindings
1726 alloc_info.allocationSize = 0x10000;
1728 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1730 vkDestroyBuffer(m_device->device(), buffer, NULL);
1734 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1735 ASSERT_VK_SUCCESS(err);
1738 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
1739 ASSERT_VK_SUCCESS(err);
1741 memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
1743 vkUnmapMemory(m_device->device(), mem);
1745 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
1746 ASSERT_VK_SUCCESS(err);
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());
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;
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;
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.
1782 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
1783 ASSERT_VK_SUCCESS(err);
1785 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
1787 mem_alloc.allocationSize = mem_reqs.size;
1789 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1791 vkDestroyImage(m_device->device(), image, NULL);
1795 // VALIDATION FAILURE:
1796 err = vkBindImageMemory(m_device->device(), image, mem, 0);
1797 ASSERT_VK_SUCCESS(err);
1799 m_errorMonitor->VerifyNotFound();
1801 vkFreeMemory(m_device->device(), mem, NULL);
1802 vkDestroyBuffer(m_device->device(), buffer, NULL);
1803 vkDestroyImage(m_device->device(), image, NULL);
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.");
1811 ASSERT_NO_FATAL_FAILURE(InitState());
1813 VkBuffer buffer, buffer2;
1816 VkDeviceMemory mem; // buffer will be bound first
1817 VkDeviceMemory mem_img; // image bound first
1818 VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
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;
1829 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1830 ASSERT_VK_SUCCESS(err);
1832 vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs);
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;
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);
1859 vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
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);
1870 vkDestroyBuffer(m_device->device(), buffer, NULL);
1871 vkDestroyImage(m_device->device(), image, NULL);
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);
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();
1884 // Now correctly bind image2 to second mem allocation before incorrectly
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();
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);
1904 TEST_F(VkLayerTest, InvalidMemoryMapping) {
1905 TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");
1908 ASSERT_NO_FATAL_FAILURE(InitState());
1912 VkMemoryRequirements mem_reqs;
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;
1923 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
1924 ASSERT_VK_SUCCESS(err);
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;
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);
1937 vkDestroyBuffer(m_device->device(), buffer, NULL);
1940 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1941 ASSERT_VK_SUCCESS(err);
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();
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();
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;
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);
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();
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);
1994 vkFreeMemory(m_device->device(), mem, NULL);
1995 vkDestroyBuffer(m_device->device(), buffer, NULL);
1998 // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of
1999 // MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver()
2001 vkDestroyBuffer(m_device->device(), buffer, NULL);
2002 vkFreeMemory(m_device->device(), mem, NULL);
2005 TEST_F(VkLayerTest, NonCoherentMemoryMapping) {
2007 TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory "
2008 "mapping while using VK_WHOLE_SIZE does not cause access "
2012 ASSERT_NO_FATAL_FAILURE(InitState());
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;
2022 static const VkDeviceSize allocation_size = 0x1000;
2023 alloc_info.allocationSize = allocation_size;
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);
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);
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);
2043 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2044 ASSERT_VK_SUCCESS(err);
2046 // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire
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;
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);
2063 // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire
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;
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);
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;
2086 mmr.offset = allocation_size - 107;
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);
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;
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);
2112 vkFreeMemory(m_device->device(), mem, NULL);
2115 TEST_F(VkLayerTest, EnableWsiBeforeUse) {
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 = {};
2129 ASSERT_NO_FATAL_FAILURE(InitState());
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:
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);
2142 m_errorMonitor->VerifyFound();
2143 #endif // VK_USE_PLATFORM_ANDROID_KHR
2145 #if defined(VK_USE_PLATFORM_MIR_KHR)
2146 // Use the functions from the VK_KHR_mir_surface extension without enabling
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);
2155 m_errorMonitor->VerifyFound();
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
2164 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
2165 // Use the functions from the VK_KHR_wayland_surface extension without
2166 // enabling that extension:
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);
2174 m_errorMonitor->VerifyFound();
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
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:
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);
2197 m_errorMonitor->VerifyFound();
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
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
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);
2220 m_errorMonitor->VerifyFound();
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
2232 #if defined(VK_USE_PLATFORM_XLIB_KHR)
2233 // Use the functions from the VK_KHR_xlib_surface extension without enabling
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);
2242 m_errorMonitor->VerifyFound();
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
2254 // Use the functions from the VK_KHR_surface extension without enabling
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();
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);
2269 m_errorMonitor->VerifyFound();
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);
2277 m_errorMonitor->VerifyFound();
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);
2286 m_errorMonitor->VerifyFound();
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);
2295 m_errorMonitor->VerifyFound();
2296 #endif // NEED_TO_TEST_THIS_ON_PLATFORM
2298 // Use the functions from the VK_KHR_swapchain extension without enabling
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);
2308 m_errorMonitor->VerifyFound();
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);
2315 m_errorMonitor->VerifyFound();
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 };
2320 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
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);
2327 m_errorMonitor->VerifyFound();
2329 vkDestroyFence(m_device->device(), fence, nullptr);
2331 // Try to present an image:
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:
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();
2343 TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) {
2345 #if defined(VK_USE_PLATFORM_XCB_KHR)
2346 VkSurfaceKHR surface = VK_NULL_HANDLE;
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 = {};
2357 ASSERT_NO_FATAL_FAILURE(InitState());
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);
2367 m_errorMonitor->VerifyFound();
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);
2377 m_errorMonitor->VerifyFound();
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;
2385 const xcb_setup_t *setup;
2386 xcb_screen_iterator_t iter;
2388 uint32_t value_mask, value_list[32];
2392 connection = xcb_connect(NULL, &scr);
2393 ASSERT_TRUE(connection != NULL);
2394 setup = xcb_get_setup(connection);
2395 iter = xcb_setup_roots_iterator(setup);
2397 xcb_screen_next(&iter);
2400 xcb_window = xcb_generate_id(connection);
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;
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);
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);
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);
2418 xcb_map_window(connection, xcb_window);
2420 // Force the x/y coordinates to 100,100 results are identical in consecutive
2422 const uint32_t coords[] = {100, 100};
2423 xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
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);
2435 // Check if surface supports presentation:
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 "
2443 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2444 pass = (err != VK_SUCCESS);
2445 // ASSERT_TRUE(pass);
2446 // m_errorMonitor->VerifyFound();
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);
2453 m_errorMonitor->VerifyFound();
2455 // Finally, do so correctly:
2456 // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2458 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
2459 pass = (err == VK_SUCCESS);
2462 // Before proceeding, try to create a swapchain without having called
2463 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
2464 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2465 swapchain_create_info.pNext = NULL;
2466 swapchain_create_info.flags = 0;
2467 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2468 "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
2469 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2470 pass = (err != VK_SUCCESS);
2472 m_errorMonitor->VerifyFound();
2474 // Get the surface capabilities:
2475 VkSurfaceCapabilitiesKHR surface_capabilities;
2477 // Do so correctly (only error logged by this entrypoint is if the
2478 // extension isn't enabled):
2479 err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
2480 pass = (err == VK_SUCCESS);
2483 // Get the surface formats:
2484 uint32_t surface_format_count;
2486 // First, try without a pointer to surface_format_count:
2487 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
2488 "specified as NULL");
2489 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
2490 pass = (err == VK_SUCCESS);
2492 m_errorMonitor->VerifyFound();
2494 // Next, call with a non-NULL pSurfaceFormats, even though we haven't
2495 // correctly done a 1st try (to get the count):
2496 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2497 surface_format_count = 0;
2498 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
2499 pass = (err == VK_SUCCESS);
2501 m_errorMonitor->VerifyFound();
2503 // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2504 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2505 pass = (err == VK_SUCCESS);
2508 // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2509 VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
2511 // Next, do a 2nd try with surface_format_count being set too high:
2512 surface_format_count += 5;
2513 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2514 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2515 pass = (err == VK_SUCCESS);
2517 m_errorMonitor->VerifyFound();
2519 // Finally, do a correct 1st and 2nd try:
2520 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2521 pass = (err == VK_SUCCESS);
2523 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2524 pass = (err == VK_SUCCESS);
2527 // Get the surface present modes:
2528 uint32_t surface_present_mode_count;
2530 // First, try without a pointer to surface_format_count:
2531 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
2532 "specified as NULL");
2534 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
2535 pass = (err == VK_SUCCESS);
2537 m_errorMonitor->VerifyFound();
2539 // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
2540 // correctly done a 1st try (to get the count):
2541 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2542 surface_present_mode_count = 0;
2543 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
2544 (VkPresentModeKHR *)&surface_present_mode_count);
2545 pass = (err == VK_SUCCESS);
2547 m_errorMonitor->VerifyFound();
2549 // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2550 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2551 pass = (err == VK_SUCCESS);
2554 // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2555 VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
2557 // Next, do a 2nd try with surface_format_count being set too high:
2558 surface_present_mode_count += 5;
2559 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2560 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2561 pass = (err == VK_SUCCESS);
2563 m_errorMonitor->VerifyFound();
2565 // Finally, do a correct 1st and 2nd try:
2566 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2567 pass = (err == VK_SUCCESS);
2569 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2570 pass = (err == VK_SUCCESS);
2573 // Create a swapchain:
2575 // First, try without a pointer to swapchain_create_info:
2576 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
2577 "specified as NULL");
2579 err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
2580 pass = (err != VK_SUCCESS);
2582 m_errorMonitor->VerifyFound();
2584 // Next, call with a non-NULL swapchain_create_info, that has the wrong
2586 swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2587 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2589 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2590 pass = (err != VK_SUCCESS);
2592 m_errorMonitor->VerifyFound();
2594 // Next, call with a NULL swapchain pointer:
2595 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2596 swapchain_create_info.pNext = NULL;
2597 swapchain_create_info.flags = 0;
2598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
2599 "specified as NULL");
2601 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
2602 pass = (err != VK_SUCCESS);
2604 m_errorMonitor->VerifyFound();
2606 // TODO: Enhance swapchain layer so that
2607 // swapchain_create_info.queueFamilyIndexCount is checked against something?
2609 // Next, call with a queue family index that's too large:
2610 uint32_t queueFamilyIndex[2] = {100000, 0};
2611 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2612 swapchain_create_info.queueFamilyIndexCount = 2;
2613 swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
2614 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2615 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2616 pass = (err != VK_SUCCESS);
2618 m_errorMonitor->VerifyFound();
2620 // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
2621 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2622 swapchain_create_info.queueFamilyIndexCount = 1;
2623 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2624 "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
2625 "pCreateInfo->pQueueFamilyIndices).");
2626 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2627 pass = (err != VK_SUCCESS);
2629 m_errorMonitor->VerifyFound();
2631 // Next, call with an invalid imageSharingMode:
2632 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
2633 swapchain_create_info.queueFamilyIndexCount = 1;
2634 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2635 "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
2636 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2637 pass = (err != VK_SUCCESS);
2639 m_errorMonitor->VerifyFound();
2640 // Fix for the future:
2641 // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2643 swapchain_create_info.queueFamilyIndexCount = 0;
2644 queueFamilyIndex[0] = 0;
2645 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
2647 // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
2648 // Get the images from a swapchain:
2649 // Acquire an image from a swapchain:
2650 // Present an image to a swapchain:
2651 // Destroy the swapchain:
2655 // - Try destroying the device without first destroying the swapchain
2657 // - Try destroying the device without first destroying the surface
2659 // - Try destroying the surface without first destroying the swapchain
2661 // Destroy the surface:
2662 vkDestroySurfaceKHR(instance(), surface, NULL);
2664 // Tear down the window:
2665 xcb_destroy_window(connection, xcb_window);
2666 xcb_disconnect(connection);
2668 #else // VK_USE_PLATFORM_XCB_KHR
2670 #endif // VK_USE_PLATFORM_XCB_KHR
2673 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2677 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2678 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2680 ASSERT_NO_FATAL_FAILURE(InitState());
2682 // Create an image, allocate memory, free it, and then try to bind it
2685 VkMemoryRequirements mem_reqs;
2687 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2688 const int32_t tex_width = 32;
2689 const int32_t tex_height = 32;
2691 VkImageCreateInfo image_create_info = {};
2692 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2693 image_create_info.pNext = NULL;
2694 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2695 image_create_info.format = tex_format;
2696 image_create_info.extent.width = tex_width;
2697 image_create_info.extent.height = tex_height;
2698 image_create_info.extent.depth = 1;
2699 image_create_info.mipLevels = 1;
2700 image_create_info.arrayLayers = 1;
2701 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2702 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2703 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2704 image_create_info.flags = 0;
2705 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2707 VkMemoryAllocateInfo mem_alloc = {};
2708 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2709 mem_alloc.pNext = NULL;
2710 mem_alloc.allocationSize = 0;
2712 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2713 ASSERT_VK_SUCCESS(err);
2715 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2717 mem_alloc.allocationSize = mem_reqs.size;
2719 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2720 if (!pass) { // If we can't find any unmappable memory this test doesn't
2722 vkDestroyImage(m_device->device(), image, NULL);
2727 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2728 ASSERT_VK_SUCCESS(err);
2730 // Try to bind free memory that has been freed
2731 err = vkBindImageMemory(m_device->device(), image, mem, 0);
2732 ASSERT_VK_SUCCESS(err);
2734 // Map memory as if to initialize the image
2735 void *mappedAddress = NULL;
2736 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2738 m_errorMonitor->VerifyFound();
2740 vkDestroyImage(m_device->device(), image, NULL);
2741 vkFreeMemory(m_device->device(), mem, NULL);
2744 TEST_F(VkLayerTest, RebindMemory) {
2748 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2750 ASSERT_NO_FATAL_FAILURE(InitState());
2752 // Create an image, allocate memory, free it, and then try to bind it
2754 VkDeviceMemory mem1;
2755 VkDeviceMemory mem2;
2756 VkMemoryRequirements mem_reqs;
2758 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2759 const int32_t tex_width = 32;
2760 const int32_t tex_height = 32;
2762 VkImageCreateInfo image_create_info = {};
2763 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2764 image_create_info.pNext = NULL;
2765 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2766 image_create_info.format = tex_format;
2767 image_create_info.extent.width = tex_width;
2768 image_create_info.extent.height = tex_height;
2769 image_create_info.extent.depth = 1;
2770 image_create_info.mipLevels = 1;
2771 image_create_info.arrayLayers = 1;
2772 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2773 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2774 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2775 image_create_info.flags = 0;
2777 VkMemoryAllocateInfo mem_alloc = {};
2778 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2779 mem_alloc.pNext = NULL;
2780 mem_alloc.allocationSize = 0;
2781 mem_alloc.memoryTypeIndex = 0;
2783 // Introduce failure, do NOT set memProps to
2784 // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2785 mem_alloc.memoryTypeIndex = 1;
2786 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2787 ASSERT_VK_SUCCESS(err);
2789 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2791 mem_alloc.allocationSize = mem_reqs.size;
2792 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2795 // allocate 2 memory objects
2796 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2797 ASSERT_VK_SUCCESS(err);
2798 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2799 ASSERT_VK_SUCCESS(err);
2801 // Bind first memory object to Image object
2802 err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2803 ASSERT_VK_SUCCESS(err);
2805 // Introduce validation failure, try to bind a different memory object to
2806 // the same image object
2807 err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2809 m_errorMonitor->VerifyFound();
2811 vkDestroyImage(m_device->device(), image, NULL);
2812 vkFreeMemory(m_device->device(), mem1, NULL);
2813 vkFreeMemory(m_device->device(), mem2, NULL);
2816 TEST_F(VkLayerTest, SubmitSignaledFence) {
2817 vk_testing::Fence testFence;
2819 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state. Fences "
2820 "must be reset before being submitted");
2822 VkFenceCreateInfo fenceInfo = {};
2823 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2824 fenceInfo.pNext = NULL;
2825 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2827 ASSERT_NO_FATAL_FAILURE(InitState());
2828 ASSERT_NO_FATAL_FAILURE(InitViewport());
2829 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2831 BeginCommandBuffer();
2832 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
2835 testFence.init(*m_device, fenceInfo);
2837 VkSubmitInfo submit_info;
2838 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2839 submit_info.pNext = NULL;
2840 submit_info.waitSemaphoreCount = 0;
2841 submit_info.pWaitSemaphores = NULL;
2842 submit_info.pWaitDstStageMask = NULL;
2843 submit_info.commandBufferCount = 1;
2844 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2845 submit_info.signalSemaphoreCount = 0;
2846 submit_info.pSignalSemaphores = NULL;
2848 vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2849 vkQueueWaitIdle(m_device->m_queue);
2851 m_errorMonitor->VerifyFound();
2853 // This is a positive test. We used to expect error in this case but spec now
2855 TEST_F(VkLayerTest, ResetUnsignaledFence) {
2856 m_errorMonitor->ExpectSuccess();
2857 vk_testing::Fence testFence;
2858 VkFenceCreateInfo fenceInfo = {};
2859 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2860 fenceInfo.pNext = NULL;
2862 ASSERT_NO_FATAL_FAILURE(InitState());
2863 testFence.init(*m_device, fenceInfo);
2864 VkFence fences[1] = {testFence.handle()};
2865 VkResult result = vkResetFences(m_device->device(), 1, fences);
2866 ASSERT_VK_SUCCESS(result);
2868 m_errorMonitor->VerifyNotFound();
2870 #if 0 // A few devices have issues with this test so disabling for now
2871 TEST_F(VkLayerTest, LongFenceChain)
2873 m_errorMonitor->ExpectSuccess();
2875 ASSERT_NO_FATAL_FAILURE(InitState());
2878 std::vector<VkFence> fences;
2880 const int chainLength = 32768;
2882 for (int i = 0; i < chainLength; i++) {
2883 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2885 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2886 ASSERT_VK_SUCCESS(err);
2888 fences.push_back(fence);
2890 VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
2891 0, nullptr, 0, nullptr };
2892 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2893 ASSERT_VK_SUCCESS(err);
2897 // BOOM, stack overflow.
2898 vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
2900 for (auto fence : fences)
2901 vkDestroyFence(m_device->device(), fence, nullptr);
2903 m_errorMonitor->VerifyNotFound();
2906 TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
2907 m_errorMonitor->ExpectSuccess();
2909 ASSERT_NO_FATAL_FAILURE(InitState());
2912 // Record (empty!) command buffer that can be submitted multiple times
2914 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2915 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
2916 m_commandBuffer->BeginCommandBuffer(&cbbi);
2917 m_commandBuffer->EndCommandBuffer();
2919 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2921 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2922 ASSERT_VK_SUCCESS(err);
2924 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
2926 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
2927 ASSERT_VK_SUCCESS(err);
2928 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
2929 ASSERT_VK_SUCCESS(err);
2931 // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
2932 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
2933 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2934 ASSERT_VK_SUCCESS(err);
2936 // Submit CB again, signaling s2.
2937 si.pSignalSemaphores = &s2;
2938 err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2939 ASSERT_VK_SUCCESS(err);
2942 err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
2943 ASSERT_VK_SUCCESS(err);
2945 // CB is still in flight from second submission, but semaphore s1 is no
2946 // longer in flight. delete it.
2947 vkDestroySemaphore(m_device->device(), s1, nullptr);
2949 m_errorMonitor->VerifyNotFound();
2951 // Force device idle and clean up remaining objects
2952 vkDeviceWaitIdle(m_device->device());
2953 vkDestroySemaphore(m_device->device(), s2, nullptr);
2954 vkDestroyFence(m_device->device(), fence, nullptr);
2957 TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
2958 m_errorMonitor->ExpectSuccess();
2960 ASSERT_NO_FATAL_FAILURE(InitState());
2963 // A fence created signaled
2964 VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
2966 err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
2967 ASSERT_VK_SUCCESS(err);
2969 // A fence created not
2970 VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2972 err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
2973 ASSERT_VK_SUCCESS(err);
2975 // Submit the unsignaled fence
2976 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
2977 err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
2979 // Wait on both fences, with signaled first.
2980 VkFence fences[] = {f1, f2};
2981 vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
2983 // Should have both retired!
2984 vkDestroyFence(m_device->device(), f1, nullptr);
2985 vkDestroyFence(m_device->device(), f2, nullptr);
2987 m_errorMonitor->VerifyNotFound();
2990 TEST_F(VkLayerTest, InvalidUsageBits) {
2991 TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
2992 "Initialize buffer with wrong usage then perform copy expecting errors "
2993 "from both the image and the buffer (2 calls)");
2994 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
2996 ASSERT_NO_FATAL_FAILURE(InitState());
2997 VkImageObj image(m_device);
2998 // Initialize image with USAGE_TRANSIENT_ATTACHMENT
2999 image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3000 ASSERT_TRUE(image.initialized());
3003 VkImageViewCreateInfo dsvci = {};
3004 dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3005 dsvci.image = image.handle();
3006 dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3007 dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
3008 dsvci.subresourceRange.layerCount = 1;
3009 dsvci.subresourceRange.baseMipLevel = 0;
3010 dsvci.subresourceRange.levelCount = 1;
3011 dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3013 // Create a view with depth / stencil aspect for image with different usage
3014 vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3016 m_errorMonitor->VerifyFound();
3018 // Initialize buffer with TRANSFER_DST usage
3019 vk_testing::Buffer buffer;
3020 VkMemoryPropertyFlags reqs = 0;
3021 buffer.init_as_dst(*m_device, 128 * 128, reqs);
3022 VkBufferImageCopy region = {};
3023 region.bufferRowLength = 128;
3024 region.bufferImageHeight = 128;
3025 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3026 region.imageSubresource.layerCount = 1;
3027 region.imageExtent.height = 16;
3028 region.imageExtent.width = 16;
3029 region.imageExtent.depth = 1;
3031 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
3032 // Buffer usage not set to TRANSFER_SRC and image usage not set to
3034 BeginCommandBuffer();
3035 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3036 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
3037 m_errorMonitor->VerifyFound();
3039 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3040 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3041 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
3042 m_errorMonitor->VerifyFound();
3045 TEST_F(VkLayerTest, ValidUsage) {
3046 TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
3047 "doesn't generate validation errors");
3049 ASSERT_NO_FATAL_FAILURE(InitState());
3051 m_errorMonitor->ExpectSuccess();
3052 // Verify that we can create a view with usage INPUT_ATTACHMENT
3053 VkImageObj image(m_device);
3054 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3055 ASSERT_TRUE(image.initialized());
3056 VkImageView imageView;
3057 VkImageViewCreateInfo ivci = {};
3058 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3059 ivci.image = image.handle();
3060 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3061 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3062 ivci.subresourceRange.layerCount = 1;
3063 ivci.subresourceRange.baseMipLevel = 0;
3064 ivci.subresourceRange.levelCount = 1;
3065 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3067 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3068 m_errorMonitor->VerifyNotFound();
3069 vkDestroyImageView(m_device->device(), imageView, NULL);
3071 #endif // MEM_TRACKER_TESTS
3073 #if OBJ_TRACKER_TESTS
3075 TEST_F(VkLayerTest, LeakAnObject) {
3078 TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3080 // Note that we have to create a new device since destroying the
3081 // framework's device causes Teardown() to fail and just calling Teardown
3082 // will destroy the errorMonitor.
3084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3086 ASSERT_NO_FATAL_FAILURE(InitState());
3088 const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
3089 std::vector<VkDeviceQueueCreateInfo> queue_info;
3090 queue_info.reserve(queue_props.size());
3091 std::vector<std::vector<float>> queue_priorities;
3092 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
3093 VkDeviceQueueCreateInfo qi = {};
3094 qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3096 qi.queueFamilyIndex = i;
3097 qi.queueCount = queue_props[i].queueCount;
3098 queue_priorities.emplace_back(qi.queueCount, 0.0f);
3099 qi.pQueuePriorities = queue_priorities[i].data();
3100 queue_info.push_back(qi);
3103 std::vector<const char *> device_extension_names;
3105 // The sacrificial device object
3106 VkDevice testDevice;
3107 VkDeviceCreateInfo device_create_info = {};
3108 auto features = m_device->phy().features();
3109 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3110 device_create_info.pNext = NULL;
3111 device_create_info.queueCreateInfoCount = queue_info.size();
3112 device_create_info.pQueueCreateInfos = queue_info.data();
3113 device_create_info.enabledLayerCount = 0;
3114 device_create_info.ppEnabledLayerNames = NULL;
3115 device_create_info.pEnabledFeatures = &features;
3116 err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3117 ASSERT_VK_SUCCESS(err);
3120 VkFenceCreateInfo fence_create_info = {};
3121 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3122 fence_create_info.pNext = NULL;
3123 fence_create_info.flags = 0;
3124 err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3125 ASSERT_VK_SUCCESS(err);
3127 // Induce failure by not calling vkDestroyFence
3128 vkDestroyDevice(testDevice, NULL);
3129 m_errorMonitor->VerifyFound();
3132 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3134 TEST_DESCRIPTION("Allocate command buffers from one command pool and "
3135 "attempt to delete them from another.");
3137 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3139 ASSERT_NO_FATAL_FAILURE(InitState());
3140 VkCommandPool command_pool_one;
3141 VkCommandPool command_pool_two;
3143 VkCommandPoolCreateInfo pool_create_info{};
3144 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3145 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3146 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3148 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3150 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3152 VkCommandBuffer command_buffer[9];
3153 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3154 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3155 command_buffer_allocate_info.commandPool = command_pool_one;
3156 command_buffer_allocate_info.commandBufferCount = 9;
3157 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3158 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3160 vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]);
3162 m_errorMonitor->VerifyFound();
3164 vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3165 vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3168 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3171 TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and "
3172 "attempt to delete them from another.");
3174 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3176 ASSERT_NO_FATAL_FAILURE(InitState());
3177 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3179 VkDescriptorPoolSize ds_type_count = {};
3180 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3181 ds_type_count.descriptorCount = 1;
3183 VkDescriptorPoolCreateInfo ds_pool_ci = {};
3184 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3185 ds_pool_ci.pNext = NULL;
3186 ds_pool_ci.flags = 0;
3187 ds_pool_ci.maxSets = 1;
3188 ds_pool_ci.poolSizeCount = 1;
3189 ds_pool_ci.pPoolSizes = &ds_type_count;
3191 VkDescriptorPool ds_pool_one;
3192 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
3193 ASSERT_VK_SUCCESS(err);
3195 // Create a second descriptor pool
3196 VkDescriptorPool ds_pool_two;
3197 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two);
3198 ASSERT_VK_SUCCESS(err);
3200 VkDescriptorSetLayoutBinding dsl_binding = {};
3201 dsl_binding.binding = 0;
3202 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3203 dsl_binding.descriptorCount = 1;
3204 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3205 dsl_binding.pImmutableSamplers = NULL;
3207 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3208 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3209 ds_layout_ci.pNext = NULL;
3210 ds_layout_ci.bindingCount = 1;
3211 ds_layout_ci.pBindings = &dsl_binding;
3213 VkDescriptorSetLayout ds_layout;
3214 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3215 ASSERT_VK_SUCCESS(err);
3217 VkDescriptorSet descriptorSet;
3218 VkDescriptorSetAllocateInfo alloc_info = {};
3219 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3220 alloc_info.descriptorSetCount = 1;
3221 alloc_info.descriptorPool = ds_pool_one;
3222 alloc_info.pSetLayouts = &ds_layout;
3223 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3224 ASSERT_VK_SUCCESS(err);
3226 err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet);
3228 m_errorMonitor->VerifyFound();
3230 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3231 vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
3232 vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL);
3235 TEST_F(VkLayerTest, CreateUnknownObject) {
3236 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3238 TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3240 ASSERT_NO_FATAL_FAILURE(InitState());
3242 // Pass bogus handle into GetImageMemoryRequirements
3243 VkMemoryRequirements mem_reqs;
3244 uint64_t fakeImageHandle = 0xCADECADE;
3245 VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3247 vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3249 m_errorMonitor->VerifyFound();
3252 TEST_F(VkLayerTest, PipelineNotBound) {
3255 TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3257 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object ");
3259 ASSERT_NO_FATAL_FAILURE(InitState());
3260 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3262 VkDescriptorPoolSize ds_type_count = {};
3263 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3264 ds_type_count.descriptorCount = 1;
3266 VkDescriptorPoolCreateInfo ds_pool_ci = {};
3267 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3268 ds_pool_ci.pNext = NULL;
3269 ds_pool_ci.maxSets = 1;
3270 ds_pool_ci.poolSizeCount = 1;
3271 ds_pool_ci.pPoolSizes = &ds_type_count;
3273 VkDescriptorPool ds_pool;
3274 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
3275 ASSERT_VK_SUCCESS(err);
3277 VkDescriptorSetLayoutBinding dsl_binding = {};
3278 dsl_binding.binding = 0;
3279 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3280 dsl_binding.descriptorCount = 1;
3281 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3282 dsl_binding.pImmutableSamplers = NULL;
3284 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3285 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3286 ds_layout_ci.pNext = NULL;
3287 ds_layout_ci.bindingCount = 1;
3288 ds_layout_ci.pBindings = &dsl_binding;
3290 VkDescriptorSetLayout ds_layout;
3291 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3292 ASSERT_VK_SUCCESS(err);
3294 VkDescriptorSet descriptorSet;
3295 VkDescriptorSetAllocateInfo alloc_info = {};
3296 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3297 alloc_info.descriptorSetCount = 1;
3298 alloc_info.descriptorPool = ds_pool;
3299 alloc_info.pSetLayouts = &ds_layout;
3300 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3301 ASSERT_VK_SUCCESS(err);
3303 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
3304 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3305 pipeline_layout_ci.pNext = NULL;
3306 pipeline_layout_ci.setLayoutCount = 1;
3307 pipeline_layout_ci.pSetLayouts = &ds_layout;
3309 VkPipelineLayout pipeline_layout;
3310 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
3311 ASSERT_VK_SUCCESS(err);
3313 VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3315 BeginCommandBuffer();
3316 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3318 m_errorMonitor->VerifyFound();
3320 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
3321 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3322 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
3325 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3328 TEST_DESCRIPTION("Test validation check for an invalid memory type index "
3329 "during bind[Buffer|Image]Memory time");
3331 ASSERT_NO_FATAL_FAILURE(InitState());
3333 // Create an image, allocate memory, set a bad typeIndex and then try to
3337 VkMemoryRequirements mem_reqs;
3338 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3339 const int32_t tex_width = 32;
3340 const int32_t tex_height = 32;
3342 VkImageCreateInfo image_create_info = {};
3343 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3344 image_create_info.pNext = NULL;
3345 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3346 image_create_info.format = tex_format;
3347 image_create_info.extent.width = tex_width;
3348 image_create_info.extent.height = tex_height;
3349 image_create_info.extent.depth = 1;
3350 image_create_info.mipLevels = 1;
3351 image_create_info.arrayLayers = 1;
3352 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3353 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3354 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3355 image_create_info.flags = 0;
3357 VkMemoryAllocateInfo mem_alloc = {};
3358 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3359 mem_alloc.pNext = NULL;
3360 mem_alloc.allocationSize = 0;
3361 mem_alloc.memoryTypeIndex = 0;
3363 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3364 ASSERT_VK_SUCCESS(err);
3366 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3367 mem_alloc.allocationSize = mem_reqs.size;
3369 // Introduce Failure, select invalid TypeIndex
3370 VkPhysicalDeviceMemoryProperties memory_info;
3372 vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3374 for (i = 0; i < memory_info.memoryTypeCount; i++) {
3375 if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3376 mem_alloc.memoryTypeIndex = i;
3380 if (i >= memory_info.memoryTypeCount) {
3381 printf("No invalid memory type index could be found; skipped.\n");
3382 vkDestroyImage(m_device->device(), image, NULL);
3386 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3388 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3389 ASSERT_VK_SUCCESS(err);
3391 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3394 m_errorMonitor->VerifyFound();
3396 vkDestroyImage(m_device->device(), image, NULL);
3397 vkFreeMemory(m_device->device(), mem, NULL);
3400 TEST_F(VkLayerTest, BindInvalidMemory) {
3404 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object ");
3406 ASSERT_NO_FATAL_FAILURE(InitState());
3408 // Create an image, allocate memory, free it, and then try to bind it
3411 VkMemoryRequirements mem_reqs;
3413 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3414 const int32_t tex_width = 32;
3415 const int32_t tex_height = 32;
3417 VkImageCreateInfo image_create_info = {};
3418 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3419 image_create_info.pNext = NULL;
3420 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3421 image_create_info.format = tex_format;
3422 image_create_info.extent.width = tex_width;
3423 image_create_info.extent.height = tex_height;
3424 image_create_info.extent.depth = 1;
3425 image_create_info.mipLevels = 1;
3426 image_create_info.arrayLayers = 1;
3427 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3428 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3429 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3430 image_create_info.flags = 0;
3432 VkMemoryAllocateInfo mem_alloc = {};
3433 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3434 mem_alloc.pNext = NULL;
3435 mem_alloc.allocationSize = 0;
3436 mem_alloc.memoryTypeIndex = 0;
3438 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3439 ASSERT_VK_SUCCESS(err);
3441 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3443 mem_alloc.allocationSize = mem_reqs.size;
3445 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3449 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3450 ASSERT_VK_SUCCESS(err);
3452 // Introduce validation failure, free memory before binding
3453 vkFreeMemory(m_device->device(), mem, NULL);
3455 // Try to bind free memory that has been freed
3456 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3457 // This may very well return an error.
3460 m_errorMonitor->VerifyFound();
3462 vkDestroyImage(m_device->device(), image, NULL);
3465 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3471 ASSERT_NO_FATAL_FAILURE(InitState());
3473 // Create an image object, allocate memory, destroy the object and then try
3477 VkMemoryRequirements mem_reqs;
3479 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3480 const int32_t tex_width = 32;
3481 const int32_t tex_height = 32;
3483 VkImageCreateInfo image_create_info = {};
3484 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3485 image_create_info.pNext = NULL;
3486 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3487 image_create_info.format = tex_format;
3488 image_create_info.extent.width = tex_width;
3489 image_create_info.extent.height = tex_height;
3490 image_create_info.extent.depth = 1;
3491 image_create_info.mipLevels = 1;
3492 image_create_info.arrayLayers = 1;
3493 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3494 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3495 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3496 image_create_info.flags = 0;
3498 VkMemoryAllocateInfo mem_alloc = {};
3499 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3500 mem_alloc.pNext = NULL;
3501 mem_alloc.allocationSize = 0;
3502 mem_alloc.memoryTypeIndex = 0;
3504 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3505 ASSERT_VK_SUCCESS(err);
3507 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3509 mem_alloc.allocationSize = mem_reqs.size;
3510 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3514 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3515 ASSERT_VK_SUCCESS(err);
3517 // Introduce validation failure, destroy Image object before binding
3518 vkDestroyImage(m_device->device(), image, NULL);
3519 ASSERT_VK_SUCCESS(err);
3521 // Now Try to bind memory to this destroyed object
3522 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3523 // This may very well return an error.
3526 m_errorMonitor->VerifyFound();
3528 vkFreeMemory(m_device->device(), mem, NULL);
3531 #endif // OBJ_TRACKER_TESTS
3533 #if DRAW_STATE_TESTS
3535 TEST_F(VkLayerTest, ImageSampleCounts) {
3537 TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger "
3538 "validation errors.");
3539 ASSERT_NO_FATAL_FAILURE(InitState());
3541 VkMemoryPropertyFlags reqs = 0;
3542 VkImageCreateInfo image_create_info = {};
3543 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3544 image_create_info.pNext = NULL;
3545 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3546 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3547 image_create_info.extent.width = 256;
3548 image_create_info.extent.height = 256;
3549 image_create_info.extent.depth = 1;
3550 image_create_info.mipLevels = 1;
3551 image_create_info.arrayLayers = 1;
3552 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3553 image_create_info.flags = 0;
3555 VkImageBlit blit_region = {};
3556 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3557 blit_region.srcSubresource.baseArrayLayer = 0;
3558 blit_region.srcSubresource.layerCount = 1;
3559 blit_region.srcSubresource.mipLevel = 0;
3560 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3561 blit_region.dstSubresource.baseArrayLayer = 0;
3562 blit_region.dstSubresource.layerCount = 1;
3563 blit_region.dstSubresource.mipLevel = 0;
3565 // Create two images, the source with sampleCount = 2, and attempt to blit
3568 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3569 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3570 vk_testing::Image src_image;
3571 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3572 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3573 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3574 vk_testing::Image dst_image;
3575 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3576 m_commandBuffer->BeginCommandBuffer();
3577 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3578 "of VK_SAMPLE_COUNT_2_BIT but "
3579 "must be VK_SAMPLE_COUNT_1_BIT");
3580 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3581 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3582 m_errorMonitor->VerifyFound();
3583 m_commandBuffer->EndCommandBuffer();
3586 // Create two images, the dest with sampleCount = 4, and attempt to blit
3589 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3590 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3591 vk_testing::Image src_image;
3592 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3593 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3594 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3595 vk_testing::Image dst_image;
3596 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3597 m_commandBuffer->BeginCommandBuffer();
3598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3599 "of VK_SAMPLE_COUNT_4_BIT but "
3600 "must be VK_SAMPLE_COUNT_1_BIT");
3601 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3602 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3603 m_errorMonitor->VerifyFound();
3604 m_commandBuffer->EndCommandBuffer();
3607 VkBufferImageCopy copy_region = {};
3608 copy_region.bufferRowLength = 128;
3609 copy_region.bufferImageHeight = 128;
3610 copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3611 copy_region.imageSubresource.layerCount = 1;
3612 copy_region.imageExtent.height = 64;
3613 copy_region.imageExtent.width = 64;
3614 copy_region.imageExtent.depth = 1;
3616 // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3619 vk_testing::Buffer src_buffer;
3620 VkMemoryPropertyFlags reqs = 0;
3621 src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3622 image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
3623 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3624 vk_testing::Image dst_image;
3625 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3626 m_commandBuffer->BeginCommandBuffer();
3627 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3628 "of VK_SAMPLE_COUNT_8_BIT but "
3629 "must be VK_SAMPLE_COUNT_1_BIT");
3630 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(),
3631 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region);
3632 m_errorMonitor->VerifyFound();
3633 m_commandBuffer->EndCommandBuffer();
3636 // Create dst buffer and src image with sampleCount = 2 and attempt to copy
3639 vk_testing::Buffer dst_buffer;
3640 dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3641 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3642 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3643 vk_testing::Image src_image;
3644 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3645 m_commandBuffer->BeginCommandBuffer();
3646 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3647 "of VK_SAMPLE_COUNT_2_BIT but "
3648 "must be VK_SAMPLE_COUNT_1_BIT");
3649 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3650 dst_buffer.handle(), 1, ©_region);
3651 m_errorMonitor->VerifyFound();
3652 m_commandBuffer->EndCommandBuffer();
3656 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
3660 TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
3661 ASSERT_NO_FATAL_FAILURE(InitState());
3663 // If w/d/h granularity is 1, test is not meaningful
3664 // TODO: When virtual device limits are available, create a set of limits for this test that
3665 // will always have a granularity of > 1 for w, h, and d
3666 auto index = m_device->graphics_queue_node_index_;
3667 auto queue_family_properties = m_device->phy().queue_properties();
3669 if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
3670 (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
3671 (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
3675 // Create two images of different types and try to copy between them
3678 VkDeviceMemory srcMem;
3679 VkDeviceMemory destMem;
3680 VkMemoryRequirements memReqs;
3682 VkImageCreateInfo image_create_info = {};
3683 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3684 image_create_info.pNext = NULL;
3685 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3686 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3687 image_create_info.extent.width = 32;
3688 image_create_info.extent.height = 32;
3689 image_create_info.extent.depth = 1;
3690 image_create_info.mipLevels = 1;
3691 image_create_info.arrayLayers = 4;
3692 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3693 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3694 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3695 image_create_info.flags = 0;
3697 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
3698 ASSERT_VK_SUCCESS(err);
3700 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
3701 ASSERT_VK_SUCCESS(err);
3704 VkMemoryAllocateInfo memAlloc = {};
3705 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3706 memAlloc.pNext = NULL;
3707 memAlloc.allocationSize = 0;
3708 memAlloc.memoryTypeIndex = 0;
3710 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
3711 memAlloc.allocationSize = memReqs.size;
3712 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3714 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
3715 ASSERT_VK_SUCCESS(err);
3717 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
3718 memAlloc.allocationSize = memReqs.size;
3719 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3720 ASSERT_VK_SUCCESS(err);
3721 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
3722 ASSERT_VK_SUCCESS(err);
3724 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
3725 ASSERT_VK_SUCCESS(err);
3726 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
3727 ASSERT_VK_SUCCESS(err);
3729 BeginCommandBuffer();
3730 VkImageCopy copyRegion;
3731 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3732 copyRegion.srcSubresource.mipLevel = 0;
3733 copyRegion.srcSubresource.baseArrayLayer = 0;
3734 copyRegion.srcSubresource.layerCount = 1;
3735 copyRegion.srcOffset.x = 0;
3736 copyRegion.srcOffset.y = 0;
3737 copyRegion.srcOffset.z = 0;
3738 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3739 copyRegion.dstSubresource.mipLevel = 0;
3740 copyRegion.dstSubresource.baseArrayLayer = 0;
3741 copyRegion.dstSubresource.layerCount = 1;
3742 copyRegion.dstOffset.x = 0;
3743 copyRegion.dstOffset.y = 0;
3744 copyRegion.dstOffset.z = 0;
3745 copyRegion.extent.width = 1;
3746 copyRegion.extent.height = 1;
3747 copyRegion.extent.depth = 1;
3749 // Introduce failure by setting srcOffset to a bad granularity value
3750 copyRegion.srcOffset.y = 3;
3751 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3752 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
3753 m_errorMonitor->VerifyFound();
3755 // Introduce failure by setting extent to a bad granularity value
3756 copyRegion.srcOffset.y = 0;
3757 copyRegion.extent.width = 3;
3758 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3759 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
3760 m_errorMonitor->VerifyFound();
3762 // Now do some buffer/image copies
3763 vk_testing::Buffer buffer;
3764 VkMemoryPropertyFlags reqs = 0;
3765 buffer.init_as_dst(*m_device, 128 * 128, reqs);
3766 VkBufferImageCopy region = {};
3767 region.bufferOffset = 0;
3768 region.bufferRowLength = 3;
3769 region.bufferImageHeight = 128;
3770 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3771 region.imageSubresource.layerCount = 1;
3772 region.imageExtent.height = 16;
3773 region.imageExtent.width = 16;
3774 region.imageExtent.depth = 1;
3775 region.imageOffset.x = 0;
3776 region.imageOffset.y = 0;
3777 region.imageOffset.z = 0;
3779 // Introduce failure by setting bufferRowLength to a bad granularity value
3780 region.bufferRowLength = 3;
3781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3782 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3784 m_errorMonitor->VerifyFound();
3785 region.bufferRowLength = 128;
3787 // Introduce failure by setting bufferOffset to a bad granularity value
3788 region.bufferOffset = 3;
3789 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3790 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3792 m_errorMonitor->VerifyFound();
3793 region.bufferOffset = 0;
3795 // Introduce failure by setting bufferImageHeight to a bad granularity value
3796 region.bufferImageHeight = 3;
3797 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3798 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3800 m_errorMonitor->VerifyFound();
3801 region.bufferImageHeight = 128;
3803 // Introduce failure by setting imageExtent to a bad granularity value
3804 region.imageExtent.width = 3;
3805 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3806 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3808 m_errorMonitor->VerifyFound();
3809 region.imageExtent.width = 16;
3811 // Introduce failure by setting imageOffset to a bad granularity value
3812 region.imageOffset.z = 3;
3813 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3814 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3816 m_errorMonitor->VerifyFound();
3820 vkDestroyImage(m_device->device(), srcImage, NULL);
3821 vkDestroyImage(m_device->device(), dstImage, NULL);
3822 vkFreeMemory(m_device->device(), srcMem, NULL);
3823 vkFreeMemory(m_device->device(), destMem, NULL);
3826 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
3827 TEST_DESCRIPTION("Submit command buffer created using one queue family and "
3828 "attempt to submit them on a queue created in a different "
3831 ASSERT_NO_FATAL_FAILURE(InitState());
3832 // This test is meaningless unless we have multiple queue families
3833 auto queue_family_properties = m_device->phy().queue_properties();
3834 if (queue_family_properties.size() < 2) {
3837 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue ");
3838 // Get safe index of another queue family
3839 uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
3840 ASSERT_NO_FATAL_FAILURE(InitState());
3841 // Create a second queue using a different queue family
3842 VkQueue other_queue;
3843 vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
3845 // Record an empty cmd buffer
3846 VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3847 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3848 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
3849 vkEndCommandBuffer(m_commandBuffer->handle());
3851 // And submit on the wrong queue
3852 VkSubmitInfo submit_info = {};
3853 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3854 submit_info.commandBufferCount = 1;
3855 submit_info.pCommandBuffers = &m_commandBuffer->handle();
3856 vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
3858 m_errorMonitor->VerifyFound();
3861 TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
3862 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
3863 "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
3864 "the command buffer has prior knowledge of that "
3865 "attachment's layout.");
3867 m_errorMonitor->ExpectSuccess();
3869 ASSERT_NO_FATAL_FAILURE(InitState());
3871 // A renderpass with one color attachment.
3872 VkAttachmentDescription attachment = {0,
3873 VK_FORMAT_R8G8B8A8_UNORM,
3874 VK_SAMPLE_COUNT_1_BIT,
3875 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3876 VK_ATTACHMENT_STORE_OP_STORE,
3877 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3878 VK_ATTACHMENT_STORE_OP_DONT_CARE,
3879 VK_IMAGE_LAYOUT_UNDEFINED,
3880 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3882 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3884 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3886 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3889 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3890 ASSERT_VK_SUCCESS(err);
3892 // A compatible framebuffer.
3893 VkImageObj image(m_device);
3894 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3895 ASSERT_TRUE(image.initialized());
3897 VkImageViewCreateInfo ivci = {
3898 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3902 VK_IMAGE_VIEW_TYPE_2D,
3903 VK_FORMAT_R8G8B8A8_UNORM,
3904 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3905 VK_COMPONENT_SWIZZLE_IDENTITY},
3906 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3909 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3910 ASSERT_VK_SUCCESS(err);
3912 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3914 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3915 ASSERT_VK_SUCCESS(err);
3917 // Record a single command buffer which uses this renderpass twice. The
3918 // bug is triggered at the beginning of the second renderpass, when the
3919 // command buffer already has a layout recorded for the attachment.
3920 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3921 BeginCommandBuffer();
3922 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3923 vkCmdEndRenderPass(m_commandBuffer->handle());
3924 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3926 m_errorMonitor->VerifyNotFound();
3928 vkCmdEndRenderPass(m_commandBuffer->handle());
3931 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3932 vkDestroyRenderPass(m_device->device(), rp, nullptr);
3933 vkDestroyImageView(m_device->device(), view, nullptr);
3936 TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
3937 TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
3938 "command buffer, bind them together, then destroy "
3939 "command pool and framebuffer and verify there are no "
3942 m_errorMonitor->ExpectSuccess();
3944 ASSERT_NO_FATAL_FAILURE(InitState());
3946 // A renderpass with one color attachment.
3947 VkAttachmentDescription attachment = {0,
3948 VK_FORMAT_R8G8B8A8_UNORM,
3949 VK_SAMPLE_COUNT_1_BIT,
3950 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3951 VK_ATTACHMENT_STORE_OP_STORE,
3952 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3953 VK_ATTACHMENT_STORE_OP_DONT_CARE,
3954 VK_IMAGE_LAYOUT_UNDEFINED,
3955 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3957 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3959 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3961 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3964 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3965 ASSERT_VK_SUCCESS(err);
3967 // A compatible framebuffer.
3968 VkImageObj image(m_device);
3969 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3970 ASSERT_TRUE(image.initialized());
3972 VkImageViewCreateInfo ivci = {
3973 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3977 VK_IMAGE_VIEW_TYPE_2D,
3978 VK_FORMAT_R8G8B8A8_UNORM,
3979 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3980 VK_COMPONENT_SWIZZLE_IDENTITY},
3981 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3984 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3985 ASSERT_VK_SUCCESS(err);
3987 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3989 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3990 ASSERT_VK_SUCCESS(err);
3992 // Explicitly create a command buffer to bind the FB to so that we can then
3993 // destroy the command pool in order to implicitly free command buffer
3994 VkCommandPool command_pool;
3995 VkCommandPoolCreateInfo pool_create_info{};
3996 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3997 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3998 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3999 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4001 VkCommandBuffer command_buffer;
4002 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4003 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4004 command_buffer_allocate_info.commandPool = command_pool;
4005 command_buffer_allocate_info.commandBufferCount = 1;
4006 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4007 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4009 // Begin our cmd buffer with renderpass using our framebuffer
4010 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4011 VkCommandBufferBeginInfo begin_info{};
4012 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4013 vkBeginCommandBuffer(command_buffer, &begin_info);
4015 vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4016 vkCmdEndRenderPass(command_buffer);
4017 vkEndCommandBuffer(command_buffer);
4018 vkDestroyImageView(m_device->device(), view, nullptr);
4019 // Destroy command pool to implicitly free command buffer
4020 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4021 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4022 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4023 m_errorMonitor->VerifyNotFound();
4026 TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
4027 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
4028 "transitions for the first subpass");
4030 m_errorMonitor->ExpectSuccess();
4032 ASSERT_NO_FATAL_FAILURE(InitState());
4034 // A renderpass with one color attachment.
4035 VkAttachmentDescription attachment = {0,
4036 VK_FORMAT_R8G8B8A8_UNORM,
4037 VK_SAMPLE_COUNT_1_BIT,
4038 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4039 VK_ATTACHMENT_STORE_OP_STORE,
4040 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4041 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4042 VK_IMAGE_LAYOUT_UNDEFINED,
4043 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4045 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4047 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4049 VkSubpassDependency dep = {0,
4051 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4052 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4053 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4054 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4055 VK_DEPENDENCY_BY_REGION_BIT};
4057 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4061 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4062 ASSERT_VK_SUCCESS(err);
4064 // A compatible framebuffer.
4065 VkImageObj image(m_device);
4066 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4067 ASSERT_TRUE(image.initialized());
4069 VkImageViewCreateInfo ivci = {
4070 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4074 VK_IMAGE_VIEW_TYPE_2D,
4075 VK_FORMAT_R8G8B8A8_UNORM,
4076 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
4077 VK_COMPONENT_SWIZZLE_IDENTITY},
4078 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
4081 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4082 ASSERT_VK_SUCCESS(err);
4084 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4086 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4087 ASSERT_VK_SUCCESS(err);
4089 // Record a single command buffer which issues a pipeline barrier w/
4090 // image memory barrier for the attachment. This detects the previously
4091 // missing tracking of the subpass layout by throwing a validation error
4092 // if it doesn't occur.
4093 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4094 BeginCommandBuffer();
4095 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4097 VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4099 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4100 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4101 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4102 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4103 VK_QUEUE_FAMILY_IGNORED,
4104 VK_QUEUE_FAMILY_IGNORED,
4106 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
4107 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4108 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4111 vkCmdEndRenderPass(m_commandBuffer->handle());
4112 m_errorMonitor->VerifyNotFound();
4115 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4116 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4117 vkDestroyImageView(m_device->device(), view, nullptr);
4120 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
4121 TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4122 ASSERT_NO_FATAL_FAILURE(InitState());
4124 // A renderpass with two subpasses, both writing the same attachment.
4125 VkAttachmentDescription attach[] = {
4126 { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
4127 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4128 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4129 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4132 VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
4133 VkSubpassDescription subpasses[] = {
4134 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4135 1, &ref, nullptr, nullptr, 0, nullptr },
4136 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4137 1, &ref, nullptr, nullptr, 0, nullptr },
4139 VkSubpassDependency dep = {
4141 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4142 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4143 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4144 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4145 VK_DEPENDENCY_BY_REGION_BIT
4147 VkRenderPassCreateInfo rpci = {
4148 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
4149 0, 1, attach, 2, subpasses, 1, &dep
4152 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4153 ASSERT_VK_SUCCESS(err);
4155 VkImageObj image(m_device);
4156 image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
4157 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4158 VK_IMAGE_TILING_OPTIMAL, 0);
4159 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4161 VkFramebufferCreateInfo fbci = {
4162 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
4163 0, rp, 1, &imageView, 32, 32, 1
4166 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4167 ASSERT_VK_SUCCESS(err);
4169 char const *vsSource =
4171 "void main() { gl_Position = vec4(1); }\n";
4172 char const *fsSource =
4174 "layout(location=0) out vec4 color;\n"
4175 "void main() { color = vec4(1); }\n";
4177 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4178 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4179 VkPipelineObj pipe(m_device);
4180 pipe.AddColorAttachment();
4181 pipe.AddShader(&vs);
4182 pipe.AddShader(&fs);
4183 VkViewport view_port = {};
4184 m_viewports.push_back(view_port);
4185 pipe.SetViewport(m_viewports);
4187 m_scissors.push_back(rect);
4188 pipe.SetScissor(m_scissors);
4190 VkPipelineLayoutCreateInfo plci = {
4191 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
4192 0, 0, nullptr, 0, nullptr
4194 VkPipelineLayout pl;
4195 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
4196 ASSERT_VK_SUCCESS(err);
4197 pipe.CreateVKPipeline(pl, rp);
4199 BeginCommandBuffer();
4201 VkRenderPassBeginInfo rpbi = {
4202 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
4203 rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
4206 // subtest 1: bind in the wrong subpass
4207 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4208 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4209 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4210 "built for subpass 0 but used in subpass 1");
4211 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4212 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4213 m_errorMonitor->VerifyFound();
4215 vkCmdEndRenderPass(m_commandBuffer->handle());
4217 // subtest 2: bind in correct subpass, then transition to next subpass
4218 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4219 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4220 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4222 "built for subpass 0 but used in subpass 1");
4223 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4224 m_errorMonitor->VerifyFound();
4226 vkCmdEndRenderPass(m_commandBuffer->handle());
4230 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
4231 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4232 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4235 TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
4236 TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
4237 "is used as a depth/stencil framebuffer attachment, the "
4238 "aspectMask is ignored and both depth and stencil image "
4239 "subresources are used.");
4241 VkFormatProperties format_properties;
4242 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
4243 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
4247 m_errorMonitor->ExpectSuccess();
4249 ASSERT_NO_FATAL_FAILURE(InitState());
4251 VkAttachmentDescription attachment = {0,
4252 VK_FORMAT_D32_SFLOAT_S8_UINT,
4253 VK_SAMPLE_COUNT_1_BIT,
4254 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4255 VK_ATTACHMENT_STORE_OP_STORE,
4256 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4257 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4258 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4259 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4261 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4263 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
4265 VkSubpassDependency dep = {0,
4267 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4268 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4269 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4270 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4271 VK_DEPENDENCY_BY_REGION_BIT};
4273 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4277 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4278 ASSERT_VK_SUCCESS(err);
4280 VkImageObj image(m_device);
4281 image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
4283 VK_IMAGE_TILING_OPTIMAL, 0);
4284 ASSERT_TRUE(image.initialized());
4285 image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
4287 VkImageViewCreateInfo ivci = {
4288 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4292 VK_IMAGE_VIEW_TYPE_2D,
4293 VK_FORMAT_D32_SFLOAT_S8_UINT,
4294 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
4298 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4299 ASSERT_VK_SUCCESS(err);
4301 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4303 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4304 ASSERT_VK_SUCCESS(err);
4306 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4307 BeginCommandBuffer();
4308 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4310 VkImageMemoryBarrier imb = {};
4311 imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4312 imb.pNext = nullptr;
4313 imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4314 imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4315 imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4316 imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4317 imb.srcQueueFamilyIndex = 0;
4318 imb.dstQueueFamilyIndex = 0;
4319 imb.image = image.handle();
4320 imb.subresourceRange.aspectMask = 0x6;
4321 imb.subresourceRange.baseMipLevel = 0;
4322 imb.subresourceRange.levelCount = 0x1;
4323 imb.subresourceRange.baseArrayLayer = 0;
4324 imb.subresourceRange.layerCount = 0x1;
4326 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4327 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4330 vkCmdEndRenderPass(m_commandBuffer->handle());
4332 QueueCommandBuffer(false);
4333 m_errorMonitor->VerifyNotFound();
4335 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4336 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4337 vkDestroyImageView(m_device->device(), view, nullptr);
4340 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
4341 TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass"
4342 "with extent outside of framebuffer");
4343 ASSERT_NO_FATAL_FAILURE(InitState());
4344 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea "
4347 "not within the bound of the framebuffer.");
4349 // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
4350 m_renderPassBeginInfo.renderArea.extent.width = 257;
4351 m_renderPassBeginInfo.renderArea.extent.height = 257;
4352 BeginCommandBuffer();
4353 m_errorMonitor->VerifyFound();
4356 TEST_F(VkLayerTest, DisabledIndependentBlend) {
4357 TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent "
4358 "blend and then specifying different blend states for two "
4360 VkPhysicalDeviceFeatures features = {};
4361 features.independentBlend = VK_FALSE;
4362 ASSERT_NO_FATAL_FAILURE(InitState(&features));
4364 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4365 "Invalid Pipeline CreateInfo: If independent blend feature not "
4366 "enabled, all elements of pAttachments must be identical");
4368 VkDescriptorSetObj descriptorSet(m_device);
4369 descriptorSet.AppendDummy();
4370 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4372 VkPipelineObj pipeline(m_device);
4373 VkRenderpassObj renderpass(m_device);
4374 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4375 pipeline.AddShader(&vs);
4377 VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
4378 att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4379 att_state1.blendEnable = VK_TRUE;
4380 att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4381 att_state2.blendEnable = VK_FALSE;
4382 pipeline.AddColorAttachment(0, &att_state1);
4383 pipeline.AddColorAttachment(1, &att_state2);
4384 pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle());
4385 m_errorMonitor->VerifyFound();
4388 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) {
4389 TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify "
4390 "depth attachments in subpass");
4391 ASSERT_NO_FATAL_FAILURE(InitState());
4393 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4394 "vkCreateRenderPass has no depth/stencil attachment, yet subpass");
4396 // Create a renderPass with a single color attachment
4397 VkAttachmentReference attach = {};
4398 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4399 VkSubpassDescription subpass = {};
4400 VkRenderPassCreateInfo rpci = {};
4401 rpci.subpassCount = 1;
4402 rpci.pSubpasses = &subpass;
4403 rpci.attachmentCount = 1;
4404 VkAttachmentDescription attach_desc = {};
4405 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4406 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4407 rpci.pAttachments = &attach_desc;
4408 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4410 subpass.pDepthStencilAttachment = &attach;
4411 subpass.pColorAttachments = NULL;
4412 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4413 m_errorMonitor->VerifyFound();
4416 TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
4417 TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
4418 "errors, when an attachment reference is "
4419 "VK_ATTACHMENT_UNUSED");
4421 m_errorMonitor->ExpectSuccess();
4423 ASSERT_NO_FATAL_FAILURE(InitState());
4425 // A renderpass with no attachments
4426 VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4428 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4430 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
4433 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4434 ASSERT_VK_SUCCESS(err);
4436 // A compatible framebuffer.
4437 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
4439 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4440 ASSERT_VK_SUCCESS(err);
4442 // Record a command buffer which just begins and ends the renderpass. The
4443 // bug manifests in BeginRenderPass.
4444 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4445 BeginCommandBuffer();
4446 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4447 vkCmdEndRenderPass(m_commandBuffer->handle());
4448 m_errorMonitor->VerifyNotFound();
4451 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4452 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4455 // This is a positive test. No errors are expected.
4456 TEST_F(VkLayerTest, StencilLoadOp) {
4457 TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
4458 "CLEAR. stencil[Load|Store]Op used to be ignored.");
4459 VkResult result = VK_SUCCESS;
4460 VkImageFormatProperties formatProps;
4461 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
4462 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
4464 if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
4468 ASSERT_NO_FATAL_FAILURE(InitState());
4469 VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
4470 m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
4471 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4472 VkAttachmentDescription att = {};
4473 VkAttachmentReference ref = {};
4474 att.format = depth_stencil_fmt;
4475 att.samples = VK_SAMPLE_COUNT_1_BIT;
4476 att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
4477 att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
4478 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
4479 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
4480 att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4481 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4484 clear.depthStencil.depth = 1.0;
4485 clear.depthStencil.stencil = 0;
4487 ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4489 VkSubpassDescription subpass = {};
4490 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4492 subpass.inputAttachmentCount = 0;
4493 subpass.pInputAttachments = NULL;
4494 subpass.colorAttachmentCount = 0;
4495 subpass.pColorAttachments = NULL;
4496 subpass.pResolveAttachments = NULL;
4497 subpass.pDepthStencilAttachment = &ref;
4498 subpass.preserveAttachmentCount = 0;
4499 subpass.pPreserveAttachments = NULL;
4502 VkRenderPassCreateInfo rp_info = {};
4503 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4504 rp_info.attachmentCount = 1;
4505 rp_info.pAttachments = &att;
4506 rp_info.subpassCount = 1;
4507 rp_info.pSubpasses = &subpass;
4508 result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
4509 ASSERT_VK_SUCCESS(result);
4511 VkImageView *depthView = m_depthStencil->BindInfo();
4512 VkFramebufferCreateInfo fb_info = {};
4513 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4514 fb_info.pNext = NULL;
4515 fb_info.renderPass = rp;
4516 fb_info.attachmentCount = 1;
4517 fb_info.pAttachments = depthView;
4518 fb_info.width = 100;
4519 fb_info.height = 100;
4522 result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4523 ASSERT_VK_SUCCESS(result);
4525 VkRenderPassBeginInfo rpbinfo = {};
4526 rpbinfo.clearValueCount = 1;
4527 rpbinfo.pClearValues = &clear;
4528 rpbinfo.pNext = NULL;
4529 rpbinfo.renderPass = rp;
4530 rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4531 rpbinfo.renderArea.extent.width = 100;
4532 rpbinfo.renderArea.extent.height = 100;
4533 rpbinfo.renderArea.offset.x = 0;
4534 rpbinfo.renderArea.offset.y = 0;
4535 rpbinfo.framebuffer = fb;
4538 VkFenceCreateInfo fence_ci = {};
4539 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4540 fence_ci.pNext = nullptr;
4542 result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
4543 ASSERT_VK_SUCCESS(result);
4545 m_commandBuffer->BeginCommandBuffer();
4546 m_commandBuffer->BeginRenderPass(rpbinfo);
4547 m_commandBuffer->EndRenderPass();
4548 m_commandBuffer->EndCommandBuffer();
4549 m_commandBuffer->QueueCommandBuffer(fence);
4551 VkImageObj destImage(m_device);
4552 destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4553 VK_IMAGE_TILING_OPTIMAL, 0);
4554 VkImageMemoryBarrier barrier = {};
4555 VkImageSubresourceRange range;
4556 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4557 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4558 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4559 barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4560 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4561 barrier.image = m_depthStencil->handle();
4562 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4563 range.baseMipLevel = 0;
4564 range.levelCount = 1;
4565 range.baseArrayLayer = 0;
4566 range.layerCount = 1;
4567 barrier.subresourceRange = range;
4568 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4569 VkCommandBufferObj cmdbuf(m_device, m_commandPool);
4570 cmdbuf.BeginCommandBuffer();
4571 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4573 barrier.srcAccessMask = 0;
4574 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4575 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4576 barrier.image = destImage.handle();
4577 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4578 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4580 VkImageCopy cregion;
4581 cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4582 cregion.srcSubresource.mipLevel = 0;
4583 cregion.srcSubresource.baseArrayLayer = 0;
4584 cregion.srcSubresource.layerCount = 1;
4585 cregion.srcOffset.x = 0;
4586 cregion.srcOffset.y = 0;
4587 cregion.srcOffset.z = 0;
4588 cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4589 cregion.dstSubresource.mipLevel = 0;
4590 cregion.dstSubresource.baseArrayLayer = 0;
4591 cregion.dstSubresource.layerCount = 1;
4592 cregion.dstOffset.x = 0;
4593 cregion.dstOffset.y = 0;
4594 cregion.dstOffset.z = 0;
4595 cregion.extent.width = 100;
4596 cregion.extent.height = 100;
4597 cregion.extent.depth = 1;
4598 cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
4599 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
4600 cmdbuf.EndCommandBuffer();
4602 VkSubmitInfo submit_info;
4603 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4604 submit_info.pNext = NULL;
4605 submit_info.waitSemaphoreCount = 0;
4606 submit_info.pWaitSemaphores = NULL;
4607 submit_info.pWaitDstStageMask = NULL;
4608 submit_info.commandBufferCount = 1;
4609 submit_info.pCommandBuffers = &cmdbuf.handle();
4610 submit_info.signalSemaphoreCount = 0;
4611 submit_info.pSignalSemaphores = NULL;
4613 m_errorMonitor->ExpectSuccess();
4614 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4615 m_errorMonitor->VerifyNotFound();
4617 vkQueueWaitIdle(m_device->m_queue);
4618 vkDestroyFence(m_device->device(), fence, nullptr);
4619 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4620 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4623 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
4624 TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
4625 "attachment reference of VK_ATTACHMENT_UNUSED");
4627 ASSERT_NO_FATAL_FAILURE(InitState());
4628 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4630 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED");
4632 VkAttachmentReference color_attach = {};
4633 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4634 color_attach.attachment = 0;
4635 uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
4636 VkSubpassDescription subpass = {};
4637 subpass.colorAttachmentCount = 1;
4638 subpass.pColorAttachments = &color_attach;
4639 subpass.preserveAttachmentCount = 1;
4640 subpass.pPreserveAttachments = &preserve_attachment;
4642 VkRenderPassCreateInfo rpci = {};
4643 rpci.subpassCount = 1;
4644 rpci.pSubpasses = &subpass;
4645 rpci.attachmentCount = 1;
4646 VkAttachmentDescription attach_desc = {};
4647 attach_desc.format = VK_FORMAT_UNDEFINED;
4648 rpci.pAttachments = &attach_desc;
4649 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4651 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4653 m_errorMonitor->VerifyFound();
4655 if (result == VK_SUCCESS) {
4656 vkDestroyRenderPass(m_device->device(), rp, NULL);
4660 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
4661 TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
4662 "when the source of a subpass multisample resolve "
4663 "does not have multiple samples.");
4665 ASSERT_NO_FATAL_FAILURE(InitState());
4667 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4668 "Subpass 0 requests multisample resolve from attachment 0 which has "
4669 "VK_SAMPLE_COUNT_1_BIT");
4671 VkAttachmentDescription attachments[] = {
4672 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4673 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4674 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4675 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4676 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4677 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4680 VkAttachmentReference color = {
4681 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4684 VkAttachmentReference resolve = {
4685 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4688 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4690 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4693 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4695 m_errorMonitor->VerifyFound();
4697 if (err == VK_SUCCESS)
4698 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4701 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
4702 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4703 "when a subpass multisample resolve operation is "
4704 "requested, and the destination of that resolve has "
4705 "multiple samples.");
4707 ASSERT_NO_FATAL_FAILURE(InitState());
4709 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4710 "Subpass 0 requests multisample resolve into attachment 1, which "
4711 "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
4713 VkAttachmentDescription attachments[] = {
4714 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4715 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4716 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4717 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4718 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4719 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4722 VkAttachmentReference color = {
4723 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4726 VkAttachmentReference resolve = {
4727 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4730 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4732 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4735 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4737 m_errorMonitor->VerifyFound();
4739 if (err == VK_SUCCESS)
4740 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4743 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
4744 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4745 "when the color and depth attachments used by a subpass "
4746 "have inconsistent sample counts");
4748 ASSERT_NO_FATAL_FAILURE(InitState());
4750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4751 "Subpass 0 attempts to render to attachments with inconsistent sample counts");
4753 VkAttachmentDescription attachments[] = {
4754 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4755 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4756 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4757 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4758 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4759 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4762 VkAttachmentReference color[] = {
4764 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4767 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4771 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr};
4773 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4776 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4778 m_errorMonitor->VerifyFound();
4780 if (err == VK_SUCCESS)
4781 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4784 TEST_F(VkLayerTest, FramebufferCreateErrors) {
4785 TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
4786 " 1. Mismatch between fb & renderPass attachmentCount\n"
4787 " 2. Use a color image as depthStencil attachment\n"
4788 " 3. Mismatch fb & renderPass attachment formats\n"
4789 " 4. Mismatch fb & renderPass attachment #samples\n"
4790 " 5. FB attachment w/ non-1 mip-levels\n"
4791 " 6. FB attachment where dimensions don't match\n"
4792 " 7. FB attachment w/o identity swizzle\n"
4793 " 8. FB dimensions exceed physical device limits\n");
4795 ASSERT_NO_FATAL_FAILURE(InitState());
4796 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4798 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4799 "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
4800 "does not match attachmentCount of 1 of ");
4802 // Create a renderPass with a single color attachment
4803 VkAttachmentReference attach = {};
4804 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4805 VkSubpassDescription subpass = {};
4806 subpass.pColorAttachments = &attach;
4807 VkRenderPassCreateInfo rpci = {};
4808 rpci.subpassCount = 1;
4809 rpci.pSubpasses = &subpass;
4810 rpci.attachmentCount = 1;
4811 VkAttachmentDescription attach_desc = {};
4812 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4813 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4814 rpci.pAttachments = &attach_desc;
4815 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4817 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4818 ASSERT_VK_SUCCESS(err);
4821 ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4822 ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4823 VkFramebufferCreateInfo fb_info = {};
4824 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4825 fb_info.pNext = NULL;
4826 fb_info.renderPass = rp;
4827 // Set mis-matching attachmentCount
4828 fb_info.attachmentCount = 2;
4829 fb_info.pAttachments = ivs;
4830 fb_info.width = 100;
4831 fb_info.height = 100;
4835 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4837 m_errorMonitor->VerifyFound();
4838 if (err == VK_SUCCESS) {
4839 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4841 vkDestroyRenderPass(m_device->device(), rp, NULL);
4843 // Create a renderPass with a depth-stencil attachment created with
4844 // IMAGE_USAGE_COLOR_ATTACHMENT
4845 // Add our color attachment to pDepthStencilAttachment
4846 subpass.pDepthStencilAttachment = &attach;
4847 subpass.pColorAttachments = NULL;
4849 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
4850 ASSERT_VK_SUCCESS(err);
4851 // Set correct attachment count, but attachment has COLOR usage bit set
4852 fb_info.attachmentCount = 1;
4853 fb_info.renderPass = rp_ds;
4855 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags ");
4856 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4858 m_errorMonitor->VerifyFound();
4859 if (err == VK_SUCCESS) {
4860 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4862 vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
4864 // Create new renderpass with alternate attachment format from fb
4865 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
4866 subpass.pDepthStencilAttachment = NULL;
4867 subpass.pColorAttachments = &attach;
4868 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4869 ASSERT_VK_SUCCESS(err);
4871 // Cause error due to mis-matched formats between rp & fb
4872 // rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
4873 fb_info.renderPass = rp;
4874 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4875 " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
4876 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4878 m_errorMonitor->VerifyFound();
4879 if (err == VK_SUCCESS) {
4880 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4882 vkDestroyRenderPass(m_device->device(), rp, NULL);
4884 // Create new renderpass with alternate sample count from fb
4885 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4886 attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
4887 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4888 ASSERT_VK_SUCCESS(err);
4890 // Cause error due to mis-matched sample count between rp & fb
4891 fb_info.renderPass = rp;
4892 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples "
4893 "that do not match the "
4894 "VK_SAMPLE_COUNT_4_BIT ");
4895 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4897 m_errorMonitor->VerifyFound();
4898 if (err == VK_SUCCESS) {
4899 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4902 vkDestroyRenderPass(m_device->device(), rp, NULL);
4904 // Create a custom imageView with non-1 mip levels
4905 VkImageObj image(m_device);
4906 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4907 ASSERT_TRUE(image.initialized());
4910 VkImageViewCreateInfo ivci = {};
4911 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4912 ivci.image = image.handle();
4913 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4914 ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4915 ivci.subresourceRange.layerCount = 1;
4916 ivci.subresourceRange.baseMipLevel = 0;
4917 // Set level count 2 (only 1 is allowed for FB attachment)
4918 ivci.subresourceRange.levelCount = 2;
4919 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4920 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4921 ASSERT_VK_SUCCESS(err);
4922 // Re-create renderpass to have matching sample count
4923 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4924 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4925 ASSERT_VK_SUCCESS(err);
4927 fb_info.renderPass = rp;
4928 fb_info.pAttachments = &view;
4929 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only ");
4930 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4932 m_errorMonitor->VerifyFound();
4933 if (err == VK_SUCCESS) {
4934 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4936 vkDestroyImageView(m_device->device(), view, NULL);
4937 // Update view to original color buffer and grow FB dimensions too big
4938 fb_info.pAttachments = ivs;
4939 fb_info.height = 1024;
4940 fb_info.width = 1024;
4942 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at "
4943 "least as large. ");
4944 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4946 m_errorMonitor->VerifyFound();
4947 if (err == VK_SUCCESS) {
4948 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4950 // Create view attachment with non-identity swizzle
4951 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4952 ivci.image = image.handle();
4953 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4954 ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4955 ivci.subresourceRange.layerCount = 1;
4956 ivci.subresourceRange.baseMipLevel = 0;
4957 ivci.subresourceRange.levelCount = 1;
4958 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4959 ivci.components.r = VK_COMPONENT_SWIZZLE_G;
4960 ivci.components.g = VK_COMPONENT_SWIZZLE_R;
4961 ivci.components.b = VK_COMPONENT_SWIZZLE_A;
4962 ivci.components.a = VK_COMPONENT_SWIZZLE_B;
4963 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4964 ASSERT_VK_SUCCESS(err);
4966 fb_info.pAttachments = &view;
4967 fb_info.height = 100;
4968 fb_info.width = 100;
4970 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All "
4971 "framebuffer attachments must have "
4972 "been created with the identity "
4974 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4976 m_errorMonitor->VerifyFound();
4977 if (err == VK_SUCCESS) {
4978 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4980 vkDestroyImageView(m_device->device(), view, NULL);
4981 // Request fb that exceeds max dimensions
4982 // reset attachment to color attachment
4983 fb_info.pAttachments = ivs;
4984 fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
4985 fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
4986 fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
4987 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo "
4988 "dimensions exceed physical device "
4990 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4992 m_errorMonitor->VerifyFound();
4993 if (err == VK_SUCCESS) {
4994 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4997 vkDestroyRenderPass(m_device->device(), rp, NULL);
5000 // This is a positive test. No errors should be generated.
5001 TEST_F(VkLayerTest, WaitEventThenSet) {
5002 TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
5004 m_errorMonitor->ExpectSuccess();
5005 ASSERT_NO_FATAL_FAILURE(InitState());
5008 VkEventCreateInfo event_create_info{};
5009 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5010 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5012 VkCommandPool command_pool;
5013 VkCommandPoolCreateInfo pool_create_info{};
5014 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5015 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5016 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5017 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5019 VkCommandBuffer command_buffer;
5020 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5021 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5022 command_buffer_allocate_info.commandPool = command_pool;
5023 command_buffer_allocate_info.commandBufferCount = 1;
5024 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5025 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5027 VkQueue queue = VK_NULL_HANDLE;
5028 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5031 VkCommandBufferBeginInfo begin_info{};
5032 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5033 vkBeginCommandBuffer(command_buffer, &begin_info);
5035 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
5036 nullptr, 0, nullptr);
5037 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5038 vkEndCommandBuffer(command_buffer);
5041 VkSubmitInfo submit_info{};
5042 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5043 submit_info.commandBufferCount = 1;
5044 submit_info.pCommandBuffers = &command_buffer;
5045 submit_info.signalSemaphoreCount = 0;
5046 submit_info.pSignalSemaphores = nullptr;
5047 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5049 { vkSetEvent(m_device->device(), event); }
5051 vkQueueWaitIdle(queue);
5053 vkDestroyEvent(m_device->device(), event, nullptr);
5054 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5055 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5057 m_errorMonitor->VerifyNotFound();
5059 // This is a positive test. No errors should be generated.
5060 TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
5061 TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
5063 ASSERT_NO_FATAL_FAILURE(InitState());
5064 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5067 m_errorMonitor->ExpectSuccess();
5069 VkQueryPool query_pool;
5070 VkQueryPoolCreateInfo query_pool_create_info{};
5071 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5072 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5073 query_pool_create_info.queryCount = 1;
5074 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5076 VkCommandPool command_pool;
5077 VkCommandPoolCreateInfo pool_create_info{};
5078 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5079 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5080 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5081 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5083 VkCommandBuffer command_buffer;
5084 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5085 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5086 command_buffer_allocate_info.commandPool = command_pool;
5087 command_buffer_allocate_info.commandBufferCount = 1;
5088 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5089 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5091 VkCommandBuffer secondary_command_buffer;
5092 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5093 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
5095 VkQueue queue = VK_NULL_HANDLE;
5096 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5099 VkBufferCreateInfo buff_create_info = {};
5100 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5101 buff_create_info.size = 1024;
5102 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5103 buff_create_info.queueFamilyIndexCount = 1;
5104 buff_create_info.pQueueFamilyIndices = &qfi;
5108 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5109 ASSERT_VK_SUCCESS(err);
5110 VkMemoryAllocateInfo mem_alloc = {};
5111 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5112 mem_alloc.pNext = NULL;
5113 mem_alloc.allocationSize = 1024;
5114 mem_alloc.memoryTypeIndex = 0;
5116 VkMemoryRequirements memReqs;
5117 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5118 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5120 vkDestroyBuffer(m_device->device(), buffer, NULL);
5125 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5126 ASSERT_VK_SUCCESS(err);
5127 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5128 ASSERT_VK_SUCCESS(err);
5130 VkCommandBufferInheritanceInfo hinfo = {};
5131 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5132 hinfo.renderPass = VK_NULL_HANDLE;
5134 hinfo.framebuffer = VK_NULL_HANDLE;
5135 hinfo.occlusionQueryEnable = VK_FALSE;
5136 hinfo.queryFlags = 0;
5137 hinfo.pipelineStatistics = 0;
5140 VkCommandBufferBeginInfo begin_info{};
5141 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5142 begin_info.pInheritanceInfo = &hinfo;
5143 vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
5145 vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
5146 vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5148 vkEndCommandBuffer(secondary_command_buffer);
5150 begin_info.pInheritanceInfo = nullptr;
5151 vkBeginCommandBuffer(command_buffer, &begin_info);
5153 vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
5154 vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
5156 vkEndCommandBuffer(command_buffer);
5159 VkSubmitInfo submit_info{};
5160 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5161 submit_info.commandBufferCount = 1;
5162 submit_info.pCommandBuffers = &command_buffer;
5163 submit_info.signalSemaphoreCount = 0;
5164 submit_info.pSignalSemaphores = nullptr;
5165 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5168 vkQueueWaitIdle(queue);
5170 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5171 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5172 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
5173 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5174 vkDestroyBuffer(m_device->device(), buffer, NULL);
5175 vkFreeMemory(m_device->device(), mem, NULL);
5177 m_errorMonitor->VerifyNotFound();
5180 // This is a positive test. No errors should be generated.
5181 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
5182 TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
5184 ASSERT_NO_FATAL_FAILURE(InitState());
5185 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5188 m_errorMonitor->ExpectSuccess();
5190 VkQueryPool query_pool;
5191 VkQueryPoolCreateInfo query_pool_create_info{};
5192 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5193 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5194 query_pool_create_info.queryCount = 1;
5195 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5197 VkCommandPool command_pool;
5198 VkCommandPoolCreateInfo pool_create_info{};
5199 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5200 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5201 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5202 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5204 VkCommandBuffer command_buffer[2];
5205 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5206 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5207 command_buffer_allocate_info.commandPool = command_pool;
5208 command_buffer_allocate_info.commandBufferCount = 2;
5209 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5210 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5212 VkQueue queue = VK_NULL_HANDLE;
5213 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5216 VkBufferCreateInfo buff_create_info = {};
5217 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5218 buff_create_info.size = 1024;
5219 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5220 buff_create_info.queueFamilyIndexCount = 1;
5221 buff_create_info.pQueueFamilyIndices = &qfi;
5225 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5226 ASSERT_VK_SUCCESS(err);
5227 VkMemoryAllocateInfo mem_alloc = {};
5228 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5229 mem_alloc.pNext = NULL;
5230 mem_alloc.allocationSize = 1024;
5231 mem_alloc.memoryTypeIndex = 0;
5233 VkMemoryRequirements memReqs;
5234 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5235 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5237 vkDestroyBuffer(m_device->device(), buffer, NULL);
5242 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5243 ASSERT_VK_SUCCESS(err);
5244 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5245 ASSERT_VK_SUCCESS(err);
5248 VkCommandBufferBeginInfo begin_info{};
5249 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5250 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5252 vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
5253 vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5255 vkEndCommandBuffer(command_buffer[0]);
5257 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5259 vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
5261 vkEndCommandBuffer(command_buffer[1]);
5264 VkSubmitInfo submit_info{};
5265 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5266 submit_info.commandBufferCount = 2;
5267 submit_info.pCommandBuffers = command_buffer;
5268 submit_info.signalSemaphoreCount = 0;
5269 submit_info.pSignalSemaphores = nullptr;
5270 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5273 vkQueueWaitIdle(queue);
5275 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5276 vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
5277 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5278 vkDestroyBuffer(m_device->device(), buffer, NULL);
5279 vkFreeMemory(m_device->device(), mem, NULL);
5281 m_errorMonitor->VerifyNotFound();
5284 TEST_F(VkLayerTest, ResetEventThenSet) {
5285 TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
5287 m_errorMonitor->ExpectSuccess();
5289 ASSERT_NO_FATAL_FAILURE(InitState());
5291 VkEventCreateInfo event_create_info{};
5292 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5293 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5295 VkCommandPool command_pool;
5296 VkCommandPoolCreateInfo pool_create_info{};
5297 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5298 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5299 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5300 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5302 VkCommandBuffer command_buffer;
5303 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5304 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5305 command_buffer_allocate_info.commandPool = command_pool;
5306 command_buffer_allocate_info.commandBufferCount = 1;
5307 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5308 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5310 VkQueue queue = VK_NULL_HANDLE;
5311 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5314 VkCommandBufferBeginInfo begin_info{};
5315 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5316 vkBeginCommandBuffer(command_buffer, &begin_info);
5318 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5319 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
5320 nullptr, 0, nullptr, 0, nullptr);
5321 vkEndCommandBuffer(command_buffer);
5324 VkSubmitInfo submit_info{};
5325 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5326 submit_info.commandBufferCount = 1;
5327 submit_info.pCommandBuffers = &command_buffer;
5328 submit_info.signalSemaphoreCount = 0;
5329 submit_info.pSignalSemaphores = nullptr;
5330 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5333 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
5335 vkSetEvent(m_device->device(), event);
5336 m_errorMonitor->VerifyFound();
5339 vkQueueWaitIdle(queue);
5341 vkDestroyEvent(m_device->device(), event, nullptr);
5342 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5343 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5346 // This is a positive test. No errors should be generated.
5347 TEST_F(VkLayerTest, TwoFencesThreeFrames) {
5348 TEST_DESCRIPTION("Two command buffers with two separate fences are each "
5349 "run through a Submit & WaitForFences cycle 3 times. This "
5350 "previously revealed a bug so running this positive test "
5351 "to prevent a regression.");
5352 m_errorMonitor->ExpectSuccess();
5354 ASSERT_NO_FATAL_FAILURE(InitState());
5355 VkQueue queue = VK_NULL_HANDLE;
5356 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5358 static const uint32_t NUM_OBJECTS = 2;
5359 static const uint32_t NUM_FRAMES = 3;
5360 VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
5361 VkFence fences[NUM_OBJECTS] = {};
5363 VkCommandPool cmd_pool;
5364 VkCommandPoolCreateInfo cmd_pool_ci = {};
5365 cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5366 cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
5367 cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5368 VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
5369 ASSERT_VK_SUCCESS(err);
5371 VkCommandBufferAllocateInfo cmd_buf_info = {};
5372 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5373 cmd_buf_info.commandPool = cmd_pool;
5374 cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5375 cmd_buf_info.commandBufferCount = 1;
5377 VkFenceCreateInfo fence_ci = {};
5378 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5379 fence_ci.pNext = nullptr;
5382 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5383 err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
5384 ASSERT_VK_SUCCESS(err);
5385 err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
5386 ASSERT_VK_SUCCESS(err);
5389 for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
5390 for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
5391 // Create empty cmd buffer
5392 VkCommandBufferBeginInfo cmdBufBeginDesc = {};
5393 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5395 err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
5396 ASSERT_VK_SUCCESS(err);
5397 err = vkEndCommandBuffer(cmd_buffers[obj]);
5398 ASSERT_VK_SUCCESS(err);
5400 VkSubmitInfo submit_info = {};
5401 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5402 submit_info.commandBufferCount = 1;
5403 submit_info.pCommandBuffers = &cmd_buffers[obj];
5404 // Submit cmd buffer and wait for fence
5405 err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
5406 ASSERT_VK_SUCCESS(err);
5407 err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
5408 ASSERT_VK_SUCCESS(err);
5409 err = vkResetFences(m_device->device(), 1, &fences[obj]);
5410 ASSERT_VK_SUCCESS(err);
5413 m_errorMonitor->VerifyNotFound();
5414 vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
5415 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5416 vkDestroyFence(m_device->device(), fences[i], nullptr);
5419 // This is a positive test. No errors should be generated.
5420 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
5422 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5423 "submitted on separate queues followed by a QueueWaitIdle.");
5425 ASSERT_NO_FATAL_FAILURE(InitState());
5426 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5429 m_errorMonitor->ExpectSuccess();
5431 VkSemaphore semaphore;
5432 VkSemaphoreCreateInfo semaphore_create_info{};
5433 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5434 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5436 VkCommandPool command_pool;
5437 VkCommandPoolCreateInfo pool_create_info{};
5438 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5439 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5440 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5441 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5443 VkCommandBuffer command_buffer[2];
5444 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5445 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5446 command_buffer_allocate_info.commandPool = command_pool;
5447 command_buffer_allocate_info.commandBufferCount = 2;
5448 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5449 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5451 VkQueue queue = VK_NULL_HANDLE;
5452 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5455 VkCommandBufferBeginInfo begin_info{};
5456 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5457 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5459 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5460 nullptr, 0, nullptr, 0, nullptr);
5462 VkViewport viewport{};
5463 viewport.maxDepth = 1.0f;
5464 viewport.minDepth = 0.0f;
5465 viewport.width = 512;
5466 viewport.height = 512;
5469 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5470 vkEndCommandBuffer(command_buffer[0]);
5473 VkCommandBufferBeginInfo begin_info{};
5474 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5475 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5477 VkViewport viewport{};
5478 viewport.maxDepth = 1.0f;
5479 viewport.minDepth = 0.0f;
5480 viewport.width = 512;
5481 viewport.height = 512;
5484 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5485 vkEndCommandBuffer(command_buffer[1]);
5488 VkSubmitInfo submit_info{};
5489 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5490 submit_info.commandBufferCount = 1;
5491 submit_info.pCommandBuffers = &command_buffer[0];
5492 submit_info.signalSemaphoreCount = 1;
5493 submit_info.pSignalSemaphores = &semaphore;
5494 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5497 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5498 VkSubmitInfo submit_info{};
5499 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5500 submit_info.commandBufferCount = 1;
5501 submit_info.pCommandBuffers = &command_buffer[1];
5502 submit_info.waitSemaphoreCount = 1;
5503 submit_info.pWaitSemaphores = &semaphore;
5504 submit_info.pWaitDstStageMask = flags;
5505 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5508 vkQueueWaitIdle(m_device->m_queue);
5510 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5511 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5512 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5514 m_errorMonitor->VerifyNotFound();
5517 // This is a positive test. No errors should be generated.
5518 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
5520 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5521 "submitted on separate queues, the second having a fence"
5522 "followed by a QueueWaitIdle.");
5524 ASSERT_NO_FATAL_FAILURE(InitState());
5525 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5528 m_errorMonitor->ExpectSuccess();
5531 VkFenceCreateInfo fence_create_info{};
5532 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5533 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5535 VkSemaphore semaphore;
5536 VkSemaphoreCreateInfo semaphore_create_info{};
5537 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5538 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5540 VkCommandPool command_pool;
5541 VkCommandPoolCreateInfo pool_create_info{};
5542 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5543 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5544 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5545 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5547 VkCommandBuffer command_buffer[2];
5548 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5549 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5550 command_buffer_allocate_info.commandPool = command_pool;
5551 command_buffer_allocate_info.commandBufferCount = 2;
5552 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5553 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5555 VkQueue queue = VK_NULL_HANDLE;
5556 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5559 VkCommandBufferBeginInfo begin_info{};
5560 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5561 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5563 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5564 nullptr, 0, nullptr, 0, nullptr);
5566 VkViewport viewport{};
5567 viewport.maxDepth = 1.0f;
5568 viewport.minDepth = 0.0f;
5569 viewport.width = 512;
5570 viewport.height = 512;
5573 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5574 vkEndCommandBuffer(command_buffer[0]);
5577 VkCommandBufferBeginInfo begin_info{};
5578 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5579 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5581 VkViewport viewport{};
5582 viewport.maxDepth = 1.0f;
5583 viewport.minDepth = 0.0f;
5584 viewport.width = 512;
5585 viewport.height = 512;
5588 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5589 vkEndCommandBuffer(command_buffer[1]);
5592 VkSubmitInfo submit_info{};
5593 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5594 submit_info.commandBufferCount = 1;
5595 submit_info.pCommandBuffers = &command_buffer[0];
5596 submit_info.signalSemaphoreCount = 1;
5597 submit_info.pSignalSemaphores = &semaphore;
5598 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5601 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5602 VkSubmitInfo submit_info{};
5603 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5604 submit_info.commandBufferCount = 1;
5605 submit_info.pCommandBuffers = &command_buffer[1];
5606 submit_info.waitSemaphoreCount = 1;
5607 submit_info.pWaitSemaphores = &semaphore;
5608 submit_info.pWaitDstStageMask = flags;
5609 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5612 vkQueueWaitIdle(m_device->m_queue);
5614 vkDestroyFence(m_device->device(), fence, nullptr);
5615 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5616 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5617 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5619 m_errorMonitor->VerifyNotFound();
5622 // This is a positive test. No errors should be generated.
5623 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
5625 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5626 "submitted on separate queues, the second having a fence"
5627 "followed by two consecutive WaitForFences calls on the same fence.");
5629 ASSERT_NO_FATAL_FAILURE(InitState());
5630 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5633 m_errorMonitor->ExpectSuccess();
5636 VkFenceCreateInfo fence_create_info{};
5637 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5638 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5640 VkSemaphore semaphore;
5641 VkSemaphoreCreateInfo semaphore_create_info{};
5642 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5643 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5645 VkCommandPool command_pool;
5646 VkCommandPoolCreateInfo pool_create_info{};
5647 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5648 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5649 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5650 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5652 VkCommandBuffer command_buffer[2];
5653 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5654 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5655 command_buffer_allocate_info.commandPool = command_pool;
5656 command_buffer_allocate_info.commandBufferCount = 2;
5657 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5658 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5660 VkQueue queue = VK_NULL_HANDLE;
5661 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5664 VkCommandBufferBeginInfo begin_info{};
5665 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5666 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5668 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5669 nullptr, 0, nullptr, 0, nullptr);
5671 VkViewport viewport{};
5672 viewport.maxDepth = 1.0f;
5673 viewport.minDepth = 0.0f;
5674 viewport.width = 512;
5675 viewport.height = 512;
5678 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5679 vkEndCommandBuffer(command_buffer[0]);
5682 VkCommandBufferBeginInfo begin_info{};
5683 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5684 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5686 VkViewport viewport{};
5687 viewport.maxDepth = 1.0f;
5688 viewport.minDepth = 0.0f;
5689 viewport.width = 512;
5690 viewport.height = 512;
5693 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5694 vkEndCommandBuffer(command_buffer[1]);
5697 VkSubmitInfo submit_info{};
5698 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5699 submit_info.commandBufferCount = 1;
5700 submit_info.pCommandBuffers = &command_buffer[0];
5701 submit_info.signalSemaphoreCount = 1;
5702 submit_info.pSignalSemaphores = &semaphore;
5703 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5706 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5707 VkSubmitInfo submit_info{};
5708 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5709 submit_info.commandBufferCount = 1;
5710 submit_info.pCommandBuffers = &command_buffer[1];
5711 submit_info.waitSemaphoreCount = 1;
5712 submit_info.pWaitSemaphores = &semaphore;
5713 submit_info.pWaitDstStageMask = flags;
5714 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5717 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5718 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5720 vkDestroyFence(m_device->device(), fence, nullptr);
5721 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5722 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5723 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5725 m_errorMonitor->VerifyNotFound();
5728 TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
5730 ASSERT_NO_FATAL_FAILURE(InitState());
5731 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
5732 printf("Test requires two queues, skipping\n");
5738 m_errorMonitor->ExpectSuccess();
5740 VkQueue q0 = m_device->m_queue;
5741 VkQueue q1 = nullptr;
5742 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
5743 ASSERT_NE(q1, nullptr);
5745 // An (empty) command buffer. We must have work in the first submission --
5746 // the layer treats unfenced work differently from fenced work.
5747 VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
5749 err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
5750 ASSERT_VK_SUCCESS(err);
5751 VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
5752 VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
5754 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
5755 ASSERT_VK_SUCCESS(err);
5756 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
5757 err = vkBeginCommandBuffer(cb, &cbbi);
5758 ASSERT_VK_SUCCESS(err);
5759 err = vkEndCommandBuffer(cb);
5760 ASSERT_VK_SUCCESS(err);
5763 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5765 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
5766 ASSERT_VK_SUCCESS(err);
5768 // First submission, to q0
5769 VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
5771 err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
5772 ASSERT_VK_SUCCESS(err);
5774 // Second submission, to q1, waiting on s
5775 VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
5776 VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
5778 err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
5779 ASSERT_VK_SUCCESS(err);
5782 err = vkQueueWaitIdle(q0);
5783 ASSERT_VK_SUCCESS(err);
5785 // Command buffer should have been completed (it was on q0); reset the pool.
5786 vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
5788 m_errorMonitor->VerifyNotFound();
5790 // Force device completely idle and clean up resources
5791 vkDeviceWaitIdle(m_device->device());
5792 vkDestroyCommandPool(m_device->device(), pool, nullptr);
5793 vkDestroySemaphore(m_device->device(), s, nullptr);
5796 // This is a positive test. No errors should be generated.
5797 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
5799 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5800 "submitted on separate queues, the second having a fence, "
5801 "followed by a WaitForFences call.");
5803 ASSERT_NO_FATAL_FAILURE(InitState());
5804 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5807 m_errorMonitor->ExpectSuccess();
5809 ASSERT_NO_FATAL_FAILURE(InitState());
5811 VkFenceCreateInfo fence_create_info{};
5812 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5813 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5815 VkSemaphore semaphore;
5816 VkSemaphoreCreateInfo semaphore_create_info{};
5817 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5818 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5820 VkCommandPool command_pool;
5821 VkCommandPoolCreateInfo pool_create_info{};
5822 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5823 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5824 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5825 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5827 VkCommandBuffer command_buffer[2];
5828 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5829 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5830 command_buffer_allocate_info.commandPool = command_pool;
5831 command_buffer_allocate_info.commandBufferCount = 2;
5832 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5833 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5835 VkQueue queue = VK_NULL_HANDLE;
5836 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5839 VkCommandBufferBeginInfo begin_info{};
5840 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5841 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5843 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5844 nullptr, 0, nullptr, 0, nullptr);
5846 VkViewport viewport{};
5847 viewport.maxDepth = 1.0f;
5848 viewport.minDepth = 0.0f;
5849 viewport.width = 512;
5850 viewport.height = 512;
5853 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5854 vkEndCommandBuffer(command_buffer[0]);
5857 VkCommandBufferBeginInfo begin_info{};
5858 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5859 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5861 VkViewport viewport{};
5862 viewport.maxDepth = 1.0f;
5863 viewport.minDepth = 0.0f;
5864 viewport.width = 512;
5865 viewport.height = 512;
5868 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5869 vkEndCommandBuffer(command_buffer[1]);
5872 VkSubmitInfo submit_info{};
5873 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5874 submit_info.commandBufferCount = 1;
5875 submit_info.pCommandBuffers = &command_buffer[0];
5876 submit_info.signalSemaphoreCount = 1;
5877 submit_info.pSignalSemaphores = &semaphore;
5878 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5881 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5882 VkSubmitInfo submit_info{};
5883 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5884 submit_info.commandBufferCount = 1;
5885 submit_info.pCommandBuffers = &command_buffer[1];
5886 submit_info.waitSemaphoreCount = 1;
5887 submit_info.pWaitSemaphores = &semaphore;
5888 submit_info.pWaitDstStageMask = flags;
5889 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5892 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5894 vkDestroyFence(m_device->device(), fence, nullptr);
5895 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5896 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5897 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5899 m_errorMonitor->VerifyNotFound();
5902 // This is a positive test. No errors should be generated.
5903 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
5905 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5906 "on the same queue, sharing a signal/wait semaphore, the "
5907 "second having a fence, "
5908 "followed by a WaitForFences call.");
5910 m_errorMonitor->ExpectSuccess();
5912 ASSERT_NO_FATAL_FAILURE(InitState());
5914 VkFenceCreateInfo fence_create_info{};
5915 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5916 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5918 VkSemaphore semaphore;
5919 VkSemaphoreCreateInfo semaphore_create_info{};
5920 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5921 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5923 VkCommandPool command_pool;
5924 VkCommandPoolCreateInfo pool_create_info{};
5925 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5926 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5927 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5928 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5930 VkCommandBuffer command_buffer[2];
5931 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5932 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5933 command_buffer_allocate_info.commandPool = command_pool;
5934 command_buffer_allocate_info.commandBufferCount = 2;
5935 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5936 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5939 VkCommandBufferBeginInfo begin_info{};
5940 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5941 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5943 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5944 nullptr, 0, nullptr, 0, nullptr);
5946 VkViewport viewport{};
5947 viewport.maxDepth = 1.0f;
5948 viewport.minDepth = 0.0f;
5949 viewport.width = 512;
5950 viewport.height = 512;
5953 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5954 vkEndCommandBuffer(command_buffer[0]);
5957 VkCommandBufferBeginInfo begin_info{};
5958 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5959 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5961 VkViewport viewport{};
5962 viewport.maxDepth = 1.0f;
5963 viewport.minDepth = 0.0f;
5964 viewport.width = 512;
5965 viewport.height = 512;
5968 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5969 vkEndCommandBuffer(command_buffer[1]);
5972 VkSubmitInfo submit_info{};
5973 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5974 submit_info.commandBufferCount = 1;
5975 submit_info.pCommandBuffers = &command_buffer[0];
5976 submit_info.signalSemaphoreCount = 1;
5977 submit_info.pSignalSemaphores = &semaphore;
5978 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5981 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5982 VkSubmitInfo submit_info{};
5983 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5984 submit_info.commandBufferCount = 1;
5985 submit_info.pCommandBuffers = &command_buffer[1];
5986 submit_info.waitSemaphoreCount = 1;
5987 submit_info.pWaitSemaphores = &semaphore;
5988 submit_info.pWaitDstStageMask = flags;
5989 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5992 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5994 vkDestroyFence(m_device->device(), fence, nullptr);
5995 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5996 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5997 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5999 m_errorMonitor->VerifyNotFound();
6002 // This is a positive test. No errors should be generated.
6003 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
6005 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6006 "on the same queue, no fences, followed by a third QueueSubmit with NO "
6007 "SubmitInfos but with a fence, followed by a WaitForFences call.");
6009 m_errorMonitor->ExpectSuccess();
6011 ASSERT_NO_FATAL_FAILURE(InitState());
6013 VkFenceCreateInfo fence_create_info{};
6014 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6015 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6017 VkCommandPool command_pool;
6018 VkCommandPoolCreateInfo pool_create_info{};
6019 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6020 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6021 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6022 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6024 VkCommandBuffer command_buffer[2];
6025 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6026 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6027 command_buffer_allocate_info.commandPool = command_pool;
6028 command_buffer_allocate_info.commandBufferCount = 2;
6029 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6030 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6033 VkCommandBufferBeginInfo begin_info{};
6034 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6035 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6037 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6038 nullptr, 0, nullptr, 0, nullptr);
6040 VkViewport viewport{};
6041 viewport.maxDepth = 1.0f;
6042 viewport.minDepth = 0.0f;
6043 viewport.width = 512;
6044 viewport.height = 512;
6047 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6048 vkEndCommandBuffer(command_buffer[0]);
6051 VkCommandBufferBeginInfo begin_info{};
6052 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6053 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6055 VkViewport viewport{};
6056 viewport.maxDepth = 1.0f;
6057 viewport.minDepth = 0.0f;
6058 viewport.width = 512;
6059 viewport.height = 512;
6062 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6063 vkEndCommandBuffer(command_buffer[1]);
6066 VkSubmitInfo submit_info{};
6067 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6068 submit_info.commandBufferCount = 1;
6069 submit_info.pCommandBuffers = &command_buffer[0];
6070 submit_info.signalSemaphoreCount = 0;
6071 submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6072 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6075 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6076 VkSubmitInfo submit_info{};
6077 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6078 submit_info.commandBufferCount = 1;
6079 submit_info.pCommandBuffers = &command_buffer[1];
6080 submit_info.waitSemaphoreCount = 0;
6081 submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6082 submit_info.pWaitDstStageMask = flags;
6083 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6086 vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
6088 VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6089 ASSERT_VK_SUCCESS(err);
6091 vkDestroyFence(m_device->device(), fence, nullptr);
6092 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6093 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6095 m_errorMonitor->VerifyNotFound();
6098 // This is a positive test. No errors should be generated.
6099 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
6101 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6102 "on the same queue, the second having a fence, followed "
6103 "by a WaitForFences call.");
6105 m_errorMonitor->ExpectSuccess();
6107 ASSERT_NO_FATAL_FAILURE(InitState());
6109 VkFenceCreateInfo fence_create_info{};
6110 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6111 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6113 VkCommandPool command_pool;
6114 VkCommandPoolCreateInfo pool_create_info{};
6115 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6116 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6117 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6118 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6120 VkCommandBuffer command_buffer[2];
6121 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6122 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6123 command_buffer_allocate_info.commandPool = command_pool;
6124 command_buffer_allocate_info.commandBufferCount = 2;
6125 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6126 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6129 VkCommandBufferBeginInfo begin_info{};
6130 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6131 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6133 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6134 nullptr, 0, nullptr, 0, nullptr);
6136 VkViewport viewport{};
6137 viewport.maxDepth = 1.0f;
6138 viewport.minDepth = 0.0f;
6139 viewport.width = 512;
6140 viewport.height = 512;
6143 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6144 vkEndCommandBuffer(command_buffer[0]);
6147 VkCommandBufferBeginInfo begin_info{};
6148 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6149 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6151 VkViewport viewport{};
6152 viewport.maxDepth = 1.0f;
6153 viewport.minDepth = 0.0f;
6154 viewport.width = 512;
6155 viewport.height = 512;
6158 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6159 vkEndCommandBuffer(command_buffer[1]);
6162 VkSubmitInfo submit_info{};
6163 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6164 submit_info.commandBufferCount = 1;
6165 submit_info.pCommandBuffers = &command_buffer[0];
6166 submit_info.signalSemaphoreCount = 0;
6167 submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6168 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6171 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6172 VkSubmitInfo submit_info{};
6173 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6174 submit_info.commandBufferCount = 1;
6175 submit_info.pCommandBuffers = &command_buffer[1];
6176 submit_info.waitSemaphoreCount = 0;
6177 submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6178 submit_info.pWaitDstStageMask = flags;
6179 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
6182 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6184 vkDestroyFence(m_device->device(), fence, nullptr);
6185 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6186 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6188 m_errorMonitor->VerifyNotFound();
6191 // This is a positive test. No errors should be generated.
6192 TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
6194 TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
6195 "QueueSubmit call followed by a WaitForFences call.");
6196 ASSERT_NO_FATAL_FAILURE(InitState());
6198 m_errorMonitor->ExpectSuccess();
6201 VkFenceCreateInfo fence_create_info{};
6202 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6203 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6205 VkSemaphore semaphore;
6206 VkSemaphoreCreateInfo semaphore_create_info{};
6207 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6208 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
6210 VkCommandPool command_pool;
6211 VkCommandPoolCreateInfo pool_create_info{};
6212 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6213 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6214 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6215 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6217 VkCommandBuffer command_buffer[2];
6218 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6219 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6220 command_buffer_allocate_info.commandPool = command_pool;
6221 command_buffer_allocate_info.commandBufferCount = 2;
6222 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6223 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6226 VkCommandBufferBeginInfo begin_info{};
6227 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6228 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6230 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6231 nullptr, 0, nullptr, 0, nullptr);
6233 VkViewport viewport{};
6234 viewport.maxDepth = 1.0f;
6235 viewport.minDepth = 0.0f;
6236 viewport.width = 512;
6237 viewport.height = 512;
6240 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6241 vkEndCommandBuffer(command_buffer[0]);
6244 VkCommandBufferBeginInfo begin_info{};
6245 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6246 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6248 VkViewport viewport{};
6249 viewport.maxDepth = 1.0f;
6250 viewport.minDepth = 0.0f;
6251 viewport.width = 512;
6252 viewport.height = 512;
6255 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6256 vkEndCommandBuffer(command_buffer[1]);
6259 VkSubmitInfo submit_info[2];
6260 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6262 submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6263 submit_info[0].pNext = NULL;
6264 submit_info[0].commandBufferCount = 1;
6265 submit_info[0].pCommandBuffers = &command_buffer[0];
6266 submit_info[0].signalSemaphoreCount = 1;
6267 submit_info[0].pSignalSemaphores = &semaphore;
6268 submit_info[0].waitSemaphoreCount = 0;
6269 submit_info[0].pWaitSemaphores = NULL;
6270 submit_info[0].pWaitDstStageMask = 0;
6272 submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6273 submit_info[1].pNext = NULL;
6274 submit_info[1].commandBufferCount = 1;
6275 submit_info[1].pCommandBuffers = &command_buffer[1];
6276 submit_info[1].waitSemaphoreCount = 1;
6277 submit_info[1].pWaitSemaphores = &semaphore;
6278 submit_info[1].pWaitDstStageMask = flags;
6279 submit_info[1].signalSemaphoreCount = 0;
6280 submit_info[1].pSignalSemaphores = NULL;
6281 vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
6284 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6286 vkDestroyFence(m_device->device(), fence, nullptr);
6287 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6288 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6289 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6291 m_errorMonitor->VerifyNotFound();
6294 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
6295 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
6296 "state is required but not correctly bound.");
6298 ASSERT_NO_FATAL_FAILURE(InitState());
6299 // Dynamic depth bias
6300 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
6301 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias);
6302 m_errorMonitor->VerifyFound();
6305 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
6306 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic "
6307 "state is required but not correctly bound.");
6309 ASSERT_NO_FATAL_FAILURE(InitState());
6310 // Dynamic line width
6311 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
6312 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth);
6313 m_errorMonitor->VerifyFound();
6316 TEST_F(VkLayerTest, DynamicViewportNotBound) {
6317 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic "
6318 "state is required but not correctly bound.");
6320 ASSERT_NO_FATAL_FAILURE(InitState());
6321 // Dynamic viewport state
6322 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, but were not provided");
6323 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
6324 m_errorMonitor->VerifyFound();
6327 TEST_F(VkLayerTest, DynamicScissorNotBound) {
6328 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic "
6329 "state is required but not correctly bound.");
6331 ASSERT_NO_FATAL_FAILURE(InitState());
6332 // Dynamic scissor state
6333 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, but were not provided");
6334 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
6335 m_errorMonitor->VerifyFound();
6338 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
6339 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants "
6340 "dynamic state is required but not correctly bound.");
6342 ASSERT_NO_FATAL_FAILURE(InitState());
6343 // Dynamic blend constant state
6344 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6345 "Dynamic blend constants state not set for this command buffer");
6346 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend);
6347 m_errorMonitor->VerifyFound();
6350 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
6351 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic "
6352 "state is required but not correctly bound.");
6354 ASSERT_NO_FATAL_FAILURE(InitState());
6355 if (!m_device->phy().features().depthBounds) {
6356 printf("Device does not support depthBounds test; skipped.\n");
6359 // Dynamic depth bounds
6360 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6361 "Dynamic depth bounds state not set for this command buffer");
6362 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds);
6363 m_errorMonitor->VerifyFound();
6366 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
6367 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic "
6368 "state is required but not correctly bound.");
6370 ASSERT_NO_FATAL_FAILURE(InitState());
6371 // Dynamic stencil read mask
6372 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6373 "Dynamic stencil read mask state not set for this command buffer");
6374 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask);
6375 m_errorMonitor->VerifyFound();
6378 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
6379 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic"
6380 " state is required but not correctly bound.");
6382 ASSERT_NO_FATAL_FAILURE(InitState());
6383 // Dynamic stencil write mask
6384 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6385 "Dynamic stencil write mask state not set for this command buffer");
6386 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask);
6387 m_errorMonitor->VerifyFound();
6390 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
6391 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic "
6392 "state is required but not correctly bound.");
6394 ASSERT_NO_FATAL_FAILURE(InitState());
6395 // Dynamic stencil reference
6396 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6397 "Dynamic stencil reference state not set for this command buffer");
6398 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference);
6399 m_errorMonitor->VerifyFound();
6402 TEST_F(VkLayerTest, IndexBufferNotBound) {
6403 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
6405 ASSERT_NO_FATAL_FAILURE(InitState());
6406 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6407 "Index buffer object not bound to this command buffer when Indexed ");
6408 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer);
6409 m_errorMonitor->VerifyFound();
6412 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
6413 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6414 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
6417 ASSERT_NO_FATAL_FAILURE(InitState());
6418 ASSERT_NO_FATAL_FAILURE(InitViewport());
6419 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6421 // We luck out b/c by default the framework creates CB w/ the
6422 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
6423 BeginCommandBuffer();
6424 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
6427 // Bypass framework since it does the waits automatically
6428 VkResult err = VK_SUCCESS;
6429 VkSubmitInfo submit_info;
6430 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6431 submit_info.pNext = NULL;
6432 submit_info.waitSemaphoreCount = 0;
6433 submit_info.pWaitSemaphores = NULL;
6434 submit_info.pWaitDstStageMask = NULL;
6435 submit_info.commandBufferCount = 1;
6436 submit_info.pCommandBuffers = &m_commandBuffer->handle();
6437 submit_info.signalSemaphoreCount = 0;
6438 submit_info.pSignalSemaphores = NULL;
6440 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6441 ASSERT_VK_SUCCESS(err);
6443 // Cause validation error by re-submitting cmd buffer that should only be
6445 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6447 m_errorMonitor->VerifyFound();
6450 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
6451 // Initiate Draw w/o a PSO bound
6454 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of "
6456 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ");
6458 ASSERT_NO_FATAL_FAILURE(InitState());
6459 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6461 // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
6462 // descriptor from it
6463 VkDescriptorPoolSize ds_type_count = {};
6464 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
6465 ds_type_count.descriptorCount = 1;
6467 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6468 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6469 ds_pool_ci.pNext = NULL;
6470 ds_pool_ci.flags = 0;
6471 ds_pool_ci.maxSets = 1;
6472 ds_pool_ci.poolSizeCount = 1;
6473 ds_pool_ci.pPoolSizes = &ds_type_count;
6475 VkDescriptorPool ds_pool;
6476 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6477 ASSERT_VK_SUCCESS(err);
6479 VkDescriptorSetLayoutBinding dsl_binding = {};
6480 dsl_binding.binding = 0;
6481 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6482 dsl_binding.descriptorCount = 1;
6483 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6484 dsl_binding.pImmutableSamplers = NULL;
6486 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6487 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6488 ds_layout_ci.pNext = NULL;
6489 ds_layout_ci.bindingCount = 1;
6490 ds_layout_ci.pBindings = &dsl_binding;
6492 VkDescriptorSetLayout ds_layout;
6493 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6494 ASSERT_VK_SUCCESS(err);
6496 VkDescriptorSet descriptorSet;
6497 VkDescriptorSetAllocateInfo alloc_info = {};
6498 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6499 alloc_info.descriptorSetCount = 1;
6500 alloc_info.descriptorPool = ds_pool;
6501 alloc_info.pSetLayouts = &ds_layout;
6502 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6504 m_errorMonitor->VerifyFound();
6506 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6507 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6510 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
6513 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6514 "It is invalid to call vkFreeDescriptorSets() with a pool created "
6515 "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
6517 ASSERT_NO_FATAL_FAILURE(InitState());
6518 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6520 VkDescriptorPoolSize ds_type_count = {};
6521 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6522 ds_type_count.descriptorCount = 1;
6524 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6525 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6526 ds_pool_ci.pNext = NULL;
6527 ds_pool_ci.maxSets = 1;
6528 ds_pool_ci.poolSizeCount = 1;
6529 ds_pool_ci.flags = 0;
6530 // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
6531 // app can only call vkResetDescriptorPool on this pool.;
6532 ds_pool_ci.pPoolSizes = &ds_type_count;
6534 VkDescriptorPool ds_pool;
6535 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6536 ASSERT_VK_SUCCESS(err);
6538 VkDescriptorSetLayoutBinding dsl_binding = {};
6539 dsl_binding.binding = 0;
6540 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6541 dsl_binding.descriptorCount = 1;
6542 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6543 dsl_binding.pImmutableSamplers = NULL;
6545 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6546 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6547 ds_layout_ci.pNext = NULL;
6548 ds_layout_ci.bindingCount = 1;
6549 ds_layout_ci.pBindings = &dsl_binding;
6551 VkDescriptorSetLayout ds_layout;
6552 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6553 ASSERT_VK_SUCCESS(err);
6555 VkDescriptorSet descriptorSet;
6556 VkDescriptorSetAllocateInfo alloc_info = {};
6557 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6558 alloc_info.descriptorSetCount = 1;
6559 alloc_info.descriptorPool = ds_pool;
6560 alloc_info.pSetLayouts = &ds_layout;
6561 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6562 ASSERT_VK_SUCCESS(err);
6564 err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
6565 m_errorMonitor->VerifyFound();
6567 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6568 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6571 TEST_F(VkLayerTest, InvalidDescriptorPool) {
6572 // Attempt to clear Descriptor Pool with bad object.
6573 // ObjectTracker should catch this.
6575 ASSERT_NO_FATAL_FAILURE(InitState());
6576 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001");
6577 uint64_t fake_pool_handle = 0xbaad6001;
6578 VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
6579 vkResetDescriptorPool(device(), bad_pool, 0);
6580 m_errorMonitor->VerifyFound();
6583 TEST_F(VkLayerTest, InvalidDescriptorSet) {
6584 // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
6585 // ObjectTracker should catch this.
6586 // Create a valid cmd buffer
6587 // call vkCmdBindDescriptorSets w/ false Descriptor Set
6589 uint64_t fake_set_handle = 0xbaad6001;
6590 VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
6592 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001");
6594 ASSERT_NO_FATAL_FAILURE(InitState());
6596 VkDescriptorSetLayoutBinding layout_bindings[1] = {};
6597 layout_bindings[0].binding = 0;
6598 layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6599 layout_bindings[0].descriptorCount = 1;
6600 layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
6601 layout_bindings[0].pImmutableSamplers = NULL;
6603 VkDescriptorSetLayout descriptor_set_layout;
6604 VkDescriptorSetLayoutCreateInfo dslci = {};
6605 dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6607 dslci.bindingCount = 1;
6608 dslci.pBindings = layout_bindings;
6609 err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout);
6610 ASSERT_VK_SUCCESS(err);
6612 VkPipelineLayout pipeline_layout;
6613 VkPipelineLayoutCreateInfo plci = {};
6614 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6616 plci.setLayoutCount = 1;
6617 plci.pSetLayouts = &descriptor_set_layout;
6618 err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6619 ASSERT_VK_SUCCESS(err);
6621 BeginCommandBuffer();
6622 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0,
6624 m_errorMonitor->VerifyFound();
6626 vkDestroyPipelineLayout(device(), pipeline_layout, NULL);
6627 vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL);
6630 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
6631 // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
6632 // ObjectTracker should catch this.
6633 uint64_t fake_layout_handle = 0xbaad6001;
6634 VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
6635 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001");
6636 ASSERT_NO_FATAL_FAILURE(InitState());
6637 VkPipelineLayout pipeline_layout;
6638 VkPipelineLayoutCreateInfo plci = {};
6639 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6641 plci.setLayoutCount = 1;
6642 plci.pSetLayouts = &bad_layout;
6643 vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6645 m_errorMonitor->VerifyFound();
6648 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
6649 TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
6650 "1) A uniform buffer update must have a valid buffer index."
6651 "2) When using an array of descriptors in a single WriteDescriptor,"
6652 " the descriptor types and stageflags must all be the same."
6653 "3) Immutable Sampler state must match across descriptors");
6655 const char *invalid_BufferInfo_ErrorMessage =
6656 "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
6657 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
6658 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
6659 const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set ";
6660 const char *immutable_ErrorMessage = "Attempting write update to descriptor set ";
6662 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
6664 ASSERT_NO_FATAL_FAILURE(InitState());
6665 VkDescriptorPoolSize ds_type_count[4] = {};
6666 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6667 ds_type_count[0].descriptorCount = 1;
6668 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6669 ds_type_count[1].descriptorCount = 1;
6670 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6671 ds_type_count[2].descriptorCount = 1;
6672 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
6673 ds_type_count[3].descriptorCount = 1;
6675 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6676 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6677 ds_pool_ci.maxSets = 1;
6678 ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
6679 ds_pool_ci.pPoolSizes = ds_type_count;
6681 VkDescriptorPool ds_pool;
6682 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6683 ASSERT_VK_SUCCESS(err);
6685 VkDescriptorSetLayoutBinding layout_binding[3] = {};
6686 layout_binding[0].binding = 0;
6687 layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6688 layout_binding[0].descriptorCount = 1;
6689 layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
6690 layout_binding[0].pImmutableSamplers = NULL;
6692 layout_binding[1].binding = 1;
6693 layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6694 layout_binding[1].descriptorCount = 1;
6695 layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6696 layout_binding[1].pImmutableSamplers = NULL;
6698 VkSamplerCreateInfo sampler_ci = {};
6699 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6700 sampler_ci.pNext = NULL;
6701 sampler_ci.magFilter = VK_FILTER_NEAREST;
6702 sampler_ci.minFilter = VK_FILTER_NEAREST;
6703 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
6704 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6705 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6706 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6707 sampler_ci.mipLodBias = 1.0;
6708 sampler_ci.anisotropyEnable = VK_FALSE;
6709 sampler_ci.maxAnisotropy = 1;
6710 sampler_ci.compareEnable = VK_FALSE;
6711 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
6712 sampler_ci.minLod = 1.0;
6713 sampler_ci.maxLod = 1.0;
6714 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
6715 sampler_ci.unnormalizedCoordinates = VK_FALSE;
6718 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
6719 ASSERT_VK_SUCCESS(err);
6721 layout_binding[2].binding = 2;
6722 layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6723 layout_binding[2].descriptorCount = 1;
6724 layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6725 layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
6727 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6728 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6729 ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
6730 ds_layout_ci.pBindings = layout_binding;
6731 VkDescriptorSetLayout ds_layout;
6732 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6733 ASSERT_VK_SUCCESS(err);
6735 VkDescriptorSetAllocateInfo alloc_info = {};
6736 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6737 alloc_info.descriptorSetCount = 1;
6738 alloc_info.descriptorPool = ds_pool;
6739 alloc_info.pSetLayouts = &ds_layout;
6740 VkDescriptorSet descriptorSet;
6741 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6742 ASSERT_VK_SUCCESS(err);
6744 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6745 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6746 pipeline_layout_ci.pNext = NULL;
6747 pipeline_layout_ci.setLayoutCount = 1;
6748 pipeline_layout_ci.pSetLayouts = &ds_layout;
6750 VkPipelineLayout pipeline_layout;
6751 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6752 ASSERT_VK_SUCCESS(err);
6754 VkWriteDescriptorSet descriptor_write = {};
6755 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6756 descriptor_write.dstSet = descriptorSet;
6757 descriptor_write.dstBinding = 0;
6758 descriptor_write.descriptorCount = 1;
6759 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6761 // 1) The uniform buffer is intentionally invalid here
6762 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6763 m_errorMonitor->VerifyFound();
6765 // Create a buffer to update the descriptor with
6767 VkBufferCreateInfo buffCI = {};
6768 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6770 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
6771 buffCI.queueFamilyIndexCount = 1;
6772 buffCI.pQueueFamilyIndices = &qfi;
6775 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
6776 ASSERT_VK_SUCCESS(err);
6777 VkDescriptorBufferInfo buffInfo = {};
6778 buffInfo.buffer = dyub;
6779 buffInfo.offset = 0;
6780 buffInfo.range = 1024;
6782 descriptor_write.pBufferInfo = &buffInfo;
6783 descriptor_write.descriptorCount = 2;
6785 // 2) The stateFlags don't match between the first and second descriptor
6786 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
6787 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6788 m_errorMonitor->VerifyFound();
6790 // 3) The second descriptor has a null_ptr pImmutableSamplers and
6791 // the third descriptor contains an immutable sampler
6792 descriptor_write.dstBinding = 1;
6793 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6795 // Make pImageInfo index non-null to avoid complaints of it missing
6796 VkDescriptorImageInfo imageInfo = {};
6797 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6798 descriptor_write.pImageInfo = &imageInfo;
6799 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
6800 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6801 m_errorMonitor->VerifyFound();
6803 vkDestroyBuffer(m_device->device(), dyub, NULL);
6804 vkDestroySampler(m_device->device(), sampler, NULL);
6805 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
6806 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6807 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6810 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
6811 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
6812 "due to a buffer dependency being destroyed.");
6813 ASSERT_NO_FATAL_FAILURE(InitState());
6817 VkMemoryRequirements mem_reqs;
6819 VkBufferCreateInfo buf_info = {};
6820 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6821 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
6822 buf_info.size = 256;
6823 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
6824 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
6825 ASSERT_VK_SUCCESS(err);
6827 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
6829 VkMemoryAllocateInfo alloc_info = {};
6830 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6831 alloc_info.allocationSize = 256;
6833 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6835 vkDestroyBuffer(m_device->device(), buffer, NULL);
6838 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
6839 ASSERT_VK_SUCCESS(err);
6841 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
6842 ASSERT_VK_SUCCESS(err);
6844 m_commandBuffer->BeginCommandBuffer();
6845 vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
6846 m_commandBuffer->EndCommandBuffer();
6848 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
6849 // Destroy buffer dependency prior to submit to cause ERROR
6850 vkDestroyBuffer(m_device->device(), buffer, NULL);
6852 VkSubmitInfo submit_info = {};
6853 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6854 submit_info.commandBufferCount = 1;
6855 submit_info.pCommandBuffers = &m_commandBuffer->handle();
6856 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6858 m_errorMonitor->VerifyFound();
6859 vkFreeMemory(m_device->handle(), mem, NULL);
6862 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
6863 TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
6865 ASSERT_NO_FATAL_FAILURE(InitState());
6866 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6868 VkDescriptorPoolSize ds_type_count;
6869 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6870 ds_type_count.descriptorCount = 1;
6872 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6873 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6874 ds_pool_ci.maxSets = 1;
6875 ds_pool_ci.poolSizeCount = 1;
6876 ds_pool_ci.pPoolSizes = &ds_type_count;
6878 VkDescriptorPool ds_pool;
6879 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6880 ASSERT_VK_SUCCESS(err);
6882 VkDescriptorSetLayoutBinding layout_binding;
6883 layout_binding.binding = 0;
6884 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6885 layout_binding.descriptorCount = 1;
6886 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6887 layout_binding.pImmutableSamplers = NULL;
6889 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6890 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6891 ds_layout_ci.bindingCount = 1;
6892 ds_layout_ci.pBindings = &layout_binding;
6893 VkDescriptorSetLayout ds_layout;
6894 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6895 ASSERT_VK_SUCCESS(err);
6897 VkDescriptorSetAllocateInfo alloc_info = {};
6898 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6899 alloc_info.descriptorSetCount = 1;
6900 alloc_info.descriptorPool = ds_pool;
6901 alloc_info.pSetLayouts = &ds_layout;
6902 VkDescriptorSet descriptor_set;
6903 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
6904 ASSERT_VK_SUCCESS(err);
6906 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6907 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6908 pipeline_layout_ci.pNext = NULL;
6909 pipeline_layout_ci.setLayoutCount = 1;
6910 pipeline_layout_ci.pSetLayouts = &ds_layout;
6912 VkPipelineLayout pipeline_layout;
6913 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6914 ASSERT_VK_SUCCESS(err);
6917 uint32_t queue_family_index = 0;
6918 VkBufferCreateInfo buffer_create_info = {};
6919 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6920 buffer_create_info.size = 1024;
6921 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
6922 buffer_create_info.queueFamilyIndexCount = 1;
6923 buffer_create_info.pQueueFamilyIndices = &queue_family_index;
6925 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
6926 ASSERT_VK_SUCCESS(err);
6928 VkMemoryRequirements memory_reqs;
6929 VkDeviceMemory buffer_memory;
6931 VkMemoryAllocateInfo memory_info = {};
6932 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6933 memory_info.allocationSize = 0;
6934 memory_info.memoryTypeIndex = 0;
6936 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
6937 memory_info.allocationSize = memory_reqs.size;
6938 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
6941 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
6942 ASSERT_VK_SUCCESS(err);
6943 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
6944 ASSERT_VK_SUCCESS(err);
6947 VkBufferViewCreateInfo bvci = {};
6948 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
6949 bvci.buffer = buffer;
6950 bvci.format = VK_FORMAT_R8_UNORM;
6951 bvci.range = VK_WHOLE_SIZE;
6953 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
6954 ASSERT_VK_SUCCESS(err);
6956 VkWriteDescriptorSet descriptor_write = {};
6957 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6958 descriptor_write.dstSet = descriptor_set;
6959 descriptor_write.dstBinding = 0;
6960 descriptor_write.descriptorCount = 1;
6961 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6962 descriptor_write.pTexelBufferView = &view;
6964 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6966 char const *vsSource = "#version 450\n"
6968 "out gl_PerVertex { \n"
6969 " vec4 gl_Position;\n"
6972 " gl_Position = vec4(1);\n"
6974 char const *fsSource = "#version 450\n"
6976 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
6977 "layout(location=0) out vec4 x;\n"
6979 " x = imageLoad(s, 0);\n"
6981 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
6982 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6983 VkPipelineObj pipe(m_device);
6984 pipe.AddShader(&vs);
6985 pipe.AddShader(&fs);
6986 pipe.AddColorAttachment();
6987 pipe.CreateVKPipeline(pipeline_layout, renderPass());
6989 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
6990 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
6992 BeginCommandBuffer();
6993 VkViewport viewport = {0, 0, 16, 16, 0, 1};
6994 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
6995 VkRect2D scissor = {{0, 0}, {16, 16}};
6996 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
6997 // Bind pipeline to cmd buffer
6998 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
6999 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7000 &descriptor_set, 0, nullptr);
7004 // Delete BufferView in order to invalidate cmd buffer
7005 vkDestroyBufferView(m_device->device(), view, NULL);
7006 // Now attempt submit of cmd buffer
7007 VkSubmitInfo submit_info = {};
7008 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7009 submit_info.commandBufferCount = 1;
7010 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7011 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7012 m_errorMonitor->VerifyFound();
7015 vkDestroyBuffer(m_device->device(), buffer, NULL);
7016 vkFreeMemory(m_device->device(), buffer_memory, NULL);
7017 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7018 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7019 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7022 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
7023 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7024 "due to an image dependency being destroyed.");
7025 ASSERT_NO_FATAL_FAILURE(InitState());
7028 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7029 VkImageCreateInfo image_create_info = {};
7030 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7031 image_create_info.pNext = NULL;
7032 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7033 image_create_info.format = tex_format;
7034 image_create_info.extent.width = 32;
7035 image_create_info.extent.height = 32;
7036 image_create_info.extent.depth = 1;
7037 image_create_info.mipLevels = 1;
7038 image_create_info.arrayLayers = 1;
7039 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7040 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7041 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7042 image_create_info.flags = 0;
7043 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7044 ASSERT_VK_SUCCESS(err);
7045 // Have to bind memory to image before recording cmd in cmd buffer using it
7046 VkMemoryRequirements mem_reqs;
7047 VkDeviceMemory image_mem;
7049 VkMemoryAllocateInfo mem_alloc = {};
7050 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7051 mem_alloc.pNext = NULL;
7052 mem_alloc.memoryTypeIndex = 0;
7053 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7054 mem_alloc.allocationSize = mem_reqs.size;
7055 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7057 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7058 ASSERT_VK_SUCCESS(err);
7059 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
7060 ASSERT_VK_SUCCESS(err);
7062 m_commandBuffer->BeginCommandBuffer();
7063 VkClearColorValue ccv;
7064 ccv.float32[0] = 1.0f;
7065 ccv.float32[1] = 1.0f;
7066 ccv.float32[2] = 1.0f;
7067 ccv.float32[3] = 1.0f;
7068 VkImageSubresourceRange isr = {};
7069 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7070 isr.baseArrayLayer = 0;
7071 isr.baseMipLevel = 0;
7074 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7075 m_commandBuffer->EndCommandBuffer();
7077 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7078 // Destroy image dependency prior to submit to cause ERROR
7079 vkDestroyImage(m_device->device(), image, NULL);
7081 VkSubmitInfo submit_info = {};
7082 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7083 submit_info.commandBufferCount = 1;
7084 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7085 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7087 m_errorMonitor->VerifyFound();
7088 vkFreeMemory(m_device->device(), image_mem, nullptr);
7091 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
7092 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7093 "due to a framebuffer image dependency being destroyed.");
7094 VkFormatProperties format_properties;
7095 VkResult err = VK_SUCCESS;
7096 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7097 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
7101 ASSERT_NO_FATAL_FAILURE(InitState());
7102 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7104 VkImageCreateInfo image_ci = {};
7105 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7106 image_ci.pNext = NULL;
7107 image_ci.imageType = VK_IMAGE_TYPE_2D;
7108 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7109 image_ci.extent.width = 32;
7110 image_ci.extent.height = 32;
7111 image_ci.extent.depth = 1;
7112 image_ci.mipLevels = 1;
7113 image_ci.arrayLayers = 1;
7114 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7115 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7116 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7117 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7120 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7122 VkMemoryRequirements memory_reqs;
7123 VkDeviceMemory image_memory;
7125 VkMemoryAllocateInfo memory_info = {};
7126 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7127 memory_info.pNext = NULL;
7128 memory_info.allocationSize = 0;
7129 memory_info.memoryTypeIndex = 0;
7130 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7131 memory_info.allocationSize = memory_reqs.size;
7132 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7134 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7135 ASSERT_VK_SUCCESS(err);
7136 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7137 ASSERT_VK_SUCCESS(err);
7139 VkImageViewCreateInfo ivci = {
7140 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7144 VK_IMAGE_VIEW_TYPE_2D,
7145 VK_FORMAT_B8G8R8A8_UNORM,
7146 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7147 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7150 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7151 ASSERT_VK_SUCCESS(err);
7153 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
7155 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7156 ASSERT_VK_SUCCESS(err);
7158 // Just use default renderpass with our framebuffer
7159 m_renderPassBeginInfo.framebuffer = fb;
7160 // Create Null cmd buffer for submit
7161 BeginCommandBuffer();
7163 // Destroy image attached to framebuffer to invalidate cmd buffer
7164 vkDestroyImage(m_device->device(), image, NULL);
7165 // Now attempt to submit cmd buffer and verify error
7166 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7167 QueueCommandBuffer(false);
7168 m_errorMonitor->VerifyFound();
7170 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7171 vkDestroyImageView(m_device->device(), view, nullptr);
7172 vkFreeMemory(m_device->device(), image_memory, nullptr);
7175 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
7176 TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
7177 VkFormatProperties format_properties;
7178 VkResult err = VK_SUCCESS;
7179 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7181 ASSERT_NO_FATAL_FAILURE(InitState());
7182 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7184 VkImageCreateInfo image_ci = {};
7185 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7186 image_ci.pNext = NULL;
7187 image_ci.imageType = VK_IMAGE_TYPE_2D;
7188 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7189 image_ci.extent.width = 256;
7190 image_ci.extent.height = 256;
7191 image_ci.extent.depth = 1;
7192 image_ci.mipLevels = 1;
7193 image_ci.arrayLayers = 1;
7194 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7195 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7196 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
7197 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7200 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7202 VkMemoryRequirements memory_reqs;
7203 VkDeviceMemory image_memory;
7205 VkMemoryAllocateInfo memory_info = {};
7206 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7207 memory_info.pNext = NULL;
7208 memory_info.allocationSize = 0;
7209 memory_info.memoryTypeIndex = 0;
7210 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7211 memory_info.allocationSize = memory_reqs.size;
7212 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7214 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7215 ASSERT_VK_SUCCESS(err);
7216 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7217 ASSERT_VK_SUCCESS(err);
7219 VkImageViewCreateInfo ivci = {
7220 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7224 VK_IMAGE_VIEW_TYPE_2D,
7225 VK_FORMAT_B8G8R8A8_UNORM,
7226 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7227 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7230 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7231 ASSERT_VK_SUCCESS(err);
7233 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
7235 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7236 ASSERT_VK_SUCCESS(err);
7238 // Just use default renderpass with our framebuffer
7239 m_renderPassBeginInfo.framebuffer = fb;
7240 // Create Null cmd buffer for submit
7241 BeginCommandBuffer();
7243 // Submit cmd buffer to put it (and attached imageView) in-flight
7244 VkSubmitInfo submit_info = {};
7245 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7246 submit_info.commandBufferCount = 1;
7247 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7248 // Submit cmd buffer to put framebuffer and children in-flight
7249 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7250 // Destroy image attached to framebuffer while in-flight
7251 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
7252 vkDestroyImage(m_device->device(), image, NULL);
7253 m_errorMonitor->VerifyFound();
7254 // Wait for queue to complete so we can safely destroy image and other objects
7255 vkQueueWaitIdle(m_device->m_queue);
7256 vkDestroyImage(m_device->device(), image, NULL);
7257 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7258 vkDestroyImageView(m_device->device(), view, nullptr);
7259 vkFreeMemory(m_device->device(), image_memory, nullptr);
7262 TEST_F(VkLayerTest, ImageMemoryNotBound) {
7263 TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
7264 ASSERT_NO_FATAL_FAILURE(InitState());
7267 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7268 VkImageCreateInfo image_create_info = {};
7269 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7270 image_create_info.pNext = NULL;
7271 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7272 image_create_info.format = tex_format;
7273 image_create_info.extent.width = 32;
7274 image_create_info.extent.height = 32;
7275 image_create_info.extent.depth = 1;
7276 image_create_info.mipLevels = 1;
7277 image_create_info.arrayLayers = 1;
7278 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7279 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7280 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7281 image_create_info.flags = 0;
7282 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7283 ASSERT_VK_SUCCESS(err);
7284 // Have to bind memory to image before recording cmd in cmd buffer using it
7285 VkMemoryRequirements mem_reqs;
7286 VkDeviceMemory image_mem;
7288 VkMemoryAllocateInfo mem_alloc = {};
7289 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7290 mem_alloc.pNext = NULL;
7291 mem_alloc.memoryTypeIndex = 0;
7292 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7293 mem_alloc.allocationSize = mem_reqs.size;
7294 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7296 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7297 ASSERT_VK_SUCCESS(err);
7299 // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
7300 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7301 " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
7303 m_commandBuffer->BeginCommandBuffer();
7304 VkClearColorValue ccv;
7305 ccv.float32[0] = 1.0f;
7306 ccv.float32[1] = 1.0f;
7307 ccv.float32[2] = 1.0f;
7308 ccv.float32[3] = 1.0f;
7309 VkImageSubresourceRange isr = {};
7310 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7311 isr.baseArrayLayer = 0;
7312 isr.baseMipLevel = 0;
7315 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7316 m_commandBuffer->EndCommandBuffer();
7318 m_errorMonitor->VerifyFound();
7319 vkDestroyImage(m_device->device(), image, NULL);
7320 vkFreeMemory(m_device->device(), image_mem, nullptr);
7323 TEST_F(VkLayerTest, BufferMemoryNotBound) {
7324 TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
7325 ASSERT_NO_FATAL_FAILURE(InitState());
7327 VkImageObj image(m_device);
7328 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7329 VK_IMAGE_TILING_OPTIMAL, 0);
7330 ASSERT_TRUE(image.initialized());
7334 VkMemoryRequirements mem_reqs;
7336 VkBufferCreateInfo buf_info = {};
7337 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7338 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
7339 buf_info.size = 256;
7340 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7341 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
7342 ASSERT_VK_SUCCESS(err);
7344 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
7346 VkMemoryAllocateInfo alloc_info = {};
7347 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7348 alloc_info.allocationSize = 256;
7350 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
7352 vkDestroyBuffer(m_device->device(), buffer, NULL);
7355 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
7356 ASSERT_VK_SUCCESS(err);
7358 // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7359 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7360 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
7361 VkBufferImageCopy region = {};
7362 region.bufferRowLength = 128;
7363 region.bufferImageHeight = 128;
7364 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7366 region.imageSubresource.layerCount = 1;
7367 region.imageExtent.height = 4;
7368 region.imageExtent.width = 4;
7369 region.imageExtent.depth = 1;
7370 m_commandBuffer->BeginCommandBuffer();
7371 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7373 m_commandBuffer->EndCommandBuffer();
7375 m_errorMonitor->VerifyFound();
7377 vkDestroyBuffer(m_device->device(), buffer, NULL);
7378 vkFreeMemory(m_device->handle(), mem, NULL);
7381 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
7382 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7383 "due to an event dependency being destroyed.");
7384 ASSERT_NO_FATAL_FAILURE(InitState());
7387 VkEventCreateInfo evci = {};
7388 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
7389 VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
7390 ASSERT_VK_SUCCESS(result);
7392 m_commandBuffer->BeginCommandBuffer();
7393 vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7394 m_commandBuffer->EndCommandBuffer();
7396 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
7397 // Destroy event dependency prior to submit to cause ERROR
7398 vkDestroyEvent(m_device->device(), event, NULL);
7400 VkSubmitInfo submit_info = {};
7401 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7402 submit_info.commandBufferCount = 1;
7403 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7404 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7406 m_errorMonitor->VerifyFound();
7409 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
7410 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7411 "due to a query pool dependency being destroyed.");
7412 ASSERT_NO_FATAL_FAILURE(InitState());
7414 VkQueryPool query_pool;
7415 VkQueryPoolCreateInfo qpci{};
7416 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7417 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
7418 qpci.queryCount = 1;
7419 VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
7420 ASSERT_VK_SUCCESS(result);
7422 m_commandBuffer->BeginCommandBuffer();
7423 vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
7424 m_commandBuffer->EndCommandBuffer();
7426 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool ");
7427 // Destroy query pool dependency prior to submit to cause ERROR
7428 vkDestroyQueryPool(m_device->device(), query_pool, NULL);
7430 VkSubmitInfo submit_info = {};
7431 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7432 submit_info.commandBufferCount = 1;
7433 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7434 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7436 m_errorMonitor->VerifyFound();
7439 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
7440 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7441 "due to a pipeline dependency being destroyed.");
7442 ASSERT_NO_FATAL_FAILURE(InitState());
7443 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7447 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7448 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7450 VkPipelineLayout pipeline_layout;
7451 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7452 ASSERT_VK_SUCCESS(err);
7454 VkPipelineViewportStateCreateInfo vp_state_ci = {};
7455 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7456 vp_state_ci.viewportCount = 1;
7457 VkViewport vp = {}; // Just need dummy vp to point to
7458 vp_state_ci.pViewports = &vp;
7459 vp_state_ci.scissorCount = 1;
7460 VkRect2D scissors = {}; // Dummy scissors to point to
7461 vp_state_ci.pScissors = &scissors;
7463 VkPipelineShaderStageCreateInfo shaderStages[2];
7464 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
7466 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7467 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
7468 // but add it to be able to run on more devices
7469 shaderStages[0] = vs.GetStageCreateInfo();
7470 shaderStages[1] = fs.GetStageCreateInfo();
7472 VkPipelineVertexInputStateCreateInfo vi_ci = {};
7473 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7475 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
7476 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7477 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
7479 VkPipelineRasterizationStateCreateInfo rs_ci = {};
7480 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7481 rs_ci.rasterizerDiscardEnable = true;
7482 rs_ci.lineWidth = 1.0f;
7484 VkPipelineColorBlendAttachmentState att = {};
7485 att.blendEnable = VK_FALSE;
7486 att.colorWriteMask = 0xf;
7488 VkPipelineColorBlendStateCreateInfo cb_ci = {};
7489 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7490 cb_ci.attachmentCount = 1;
7491 cb_ci.pAttachments = &att;
7493 VkGraphicsPipelineCreateInfo gp_ci = {};
7494 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7495 gp_ci.stageCount = 2;
7496 gp_ci.pStages = shaderStages;
7497 gp_ci.pVertexInputState = &vi_ci;
7498 gp_ci.pInputAssemblyState = &ia_ci;
7499 gp_ci.pViewportState = &vp_state_ci;
7500 gp_ci.pRasterizationState = &rs_ci;
7501 gp_ci.pColorBlendState = &cb_ci;
7502 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
7503 gp_ci.layout = pipeline_layout;
7504 gp_ci.renderPass = renderPass();
7506 VkPipelineCacheCreateInfo pc_ci = {};
7507 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
7509 VkPipeline pipeline;
7510 VkPipelineCache pipelineCache;
7511 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
7512 ASSERT_VK_SUCCESS(err);
7514 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
7515 ASSERT_VK_SUCCESS(err);
7517 m_commandBuffer->BeginCommandBuffer();
7518 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
7519 m_commandBuffer->EndCommandBuffer();
7520 // Now destroy pipeline in order to cause error when submitting
7521 vkDestroyPipeline(m_device->device(), pipeline, nullptr);
7523 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline ");
7525 VkSubmitInfo submit_info = {};
7526 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7527 submit_info.commandBufferCount = 1;
7528 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7529 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7531 m_errorMonitor->VerifyFound();
7532 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
7533 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7536 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
7537 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7538 "due to a bound descriptor set with a buffer dependency "
7539 "being destroyed.");
7540 ASSERT_NO_FATAL_FAILURE(InitState());
7541 ASSERT_NO_FATAL_FAILURE(InitViewport());
7542 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7544 VkDescriptorPoolSize ds_type_count = {};
7545 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7546 ds_type_count.descriptorCount = 1;
7548 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7549 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7550 ds_pool_ci.pNext = NULL;
7551 ds_pool_ci.maxSets = 1;
7552 ds_pool_ci.poolSizeCount = 1;
7553 ds_pool_ci.pPoolSizes = &ds_type_count;
7555 VkDescriptorPool ds_pool;
7556 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7557 ASSERT_VK_SUCCESS(err);
7559 VkDescriptorSetLayoutBinding dsl_binding = {};
7560 dsl_binding.binding = 0;
7561 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7562 dsl_binding.descriptorCount = 1;
7563 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7564 dsl_binding.pImmutableSamplers = NULL;
7566 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7567 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7568 ds_layout_ci.pNext = NULL;
7569 ds_layout_ci.bindingCount = 1;
7570 ds_layout_ci.pBindings = &dsl_binding;
7571 VkDescriptorSetLayout ds_layout;
7572 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7573 ASSERT_VK_SUCCESS(err);
7575 VkDescriptorSet descriptorSet;
7576 VkDescriptorSetAllocateInfo alloc_info = {};
7577 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7578 alloc_info.descriptorSetCount = 1;
7579 alloc_info.descriptorPool = ds_pool;
7580 alloc_info.pSetLayouts = &ds_layout;
7581 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7582 ASSERT_VK_SUCCESS(err);
7584 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7585 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7586 pipeline_layout_ci.pNext = NULL;
7587 pipeline_layout_ci.setLayoutCount = 1;
7588 pipeline_layout_ci.pSetLayouts = &ds_layout;
7590 VkPipelineLayout pipeline_layout;
7591 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7592 ASSERT_VK_SUCCESS(err);
7594 // Create a buffer to update the descriptor with
7596 VkBufferCreateInfo buffCI = {};
7597 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7599 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
7600 buffCI.queueFamilyIndexCount = 1;
7601 buffCI.pQueueFamilyIndices = &qfi;
7604 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
7605 ASSERT_VK_SUCCESS(err);
7606 // Allocate memory and bind to buffer so we can make it to the appropriate
7608 VkMemoryAllocateInfo mem_alloc = {};
7609 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7610 mem_alloc.pNext = NULL;
7611 mem_alloc.allocationSize = 1024;
7612 mem_alloc.memoryTypeIndex = 0;
7614 VkMemoryRequirements memReqs;
7615 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
7616 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
7618 vkDestroyBuffer(m_device->device(), buffer, NULL);
7623 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
7624 ASSERT_VK_SUCCESS(err);
7625 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7626 ASSERT_VK_SUCCESS(err);
7627 // Correctly update descriptor to avoid "NOT_UPDATED" error
7628 VkDescriptorBufferInfo buffInfo = {};
7629 buffInfo.buffer = buffer;
7630 buffInfo.offset = 0;
7631 buffInfo.range = 1024;
7633 VkWriteDescriptorSet descriptor_write;
7634 memset(&descriptor_write, 0, sizeof(descriptor_write));
7635 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7636 descriptor_write.dstSet = descriptorSet;
7637 descriptor_write.dstBinding = 0;
7638 descriptor_write.descriptorCount = 1;
7639 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7640 descriptor_write.pBufferInfo = &buffInfo;
7642 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7644 // Create PSO to be used for draw-time errors below
7645 char const *vsSource = "#version 450\n"
7647 "out gl_PerVertex { \n"
7648 " vec4 gl_Position;\n"
7651 " gl_Position = vec4(1);\n"
7653 char const *fsSource = "#version 450\n"
7655 "layout(location=0) out vec4 x;\n"
7656 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
7658 " x = vec4(bar.y);\n"
7660 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7661 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7662 VkPipelineObj pipe(m_device);
7663 pipe.AddShader(&vs);
7664 pipe.AddShader(&fs);
7665 pipe.AddColorAttachment();
7666 pipe.CreateVKPipeline(pipeline_layout, renderPass());
7668 BeginCommandBuffer();
7669 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7670 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7671 &descriptorSet, 0, NULL);
7674 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
7675 // Destroy buffer should invalidate the cmd buffer, causing error on submit
7676 vkDestroyBuffer(m_device->device(), buffer, NULL);
7677 // Attempt to submit cmd buffer
7678 VkSubmitInfo submit_info = {};
7679 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7680 submit_info.commandBufferCount = 1;
7681 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7682 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7683 m_errorMonitor->VerifyFound();
7685 vkFreeMemory(m_device->device(), mem, NULL);
7687 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7688 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7689 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7692 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
7693 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7694 "due to a bound descriptor sets with a combined image "
7695 "sampler having their image, sampler, and descriptor set "
7696 "each respectively destroyed and then attempting to "
7697 "submit associated cmd buffers. Attempt to destroy a "
7698 "DescriptorSet that is in use.");
7699 ASSERT_NO_FATAL_FAILURE(InitState());
7700 ASSERT_NO_FATAL_FAILURE(InitViewport());
7701 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7703 VkDescriptorPoolSize ds_type_count = {};
7704 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7705 ds_type_count.descriptorCount = 1;
7707 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7708 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7709 ds_pool_ci.pNext = NULL;
7710 ds_pool_ci.maxSets = 1;
7711 ds_pool_ci.poolSizeCount = 1;
7712 ds_pool_ci.pPoolSizes = &ds_type_count;
7714 VkDescriptorPool ds_pool;
7715 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7716 ASSERT_VK_SUCCESS(err);
7718 VkDescriptorSetLayoutBinding dsl_binding = {};
7719 dsl_binding.binding = 0;
7720 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7721 dsl_binding.descriptorCount = 1;
7722 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7723 dsl_binding.pImmutableSamplers = NULL;
7725 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7726 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7727 ds_layout_ci.pNext = NULL;
7728 ds_layout_ci.bindingCount = 1;
7729 ds_layout_ci.pBindings = &dsl_binding;
7730 VkDescriptorSetLayout ds_layout;
7731 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7732 ASSERT_VK_SUCCESS(err);
7734 VkDescriptorSet descriptorSet;
7735 VkDescriptorSetAllocateInfo alloc_info = {};
7736 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7737 alloc_info.descriptorSetCount = 1;
7738 alloc_info.descriptorPool = ds_pool;
7739 alloc_info.pSetLayouts = &ds_layout;
7740 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7741 ASSERT_VK_SUCCESS(err);
7743 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7744 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7745 pipeline_layout_ci.pNext = NULL;
7746 pipeline_layout_ci.setLayoutCount = 1;
7747 pipeline_layout_ci.pSetLayouts = &ds_layout;
7749 VkPipelineLayout pipeline_layout;
7750 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7751 ASSERT_VK_SUCCESS(err);
7753 // Create images to update the descriptor with
7756 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7757 const int32_t tex_width = 32;
7758 const int32_t tex_height = 32;
7759 VkImageCreateInfo image_create_info = {};
7760 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7761 image_create_info.pNext = NULL;
7762 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7763 image_create_info.format = tex_format;
7764 image_create_info.extent.width = tex_width;
7765 image_create_info.extent.height = tex_height;
7766 image_create_info.extent.depth = 1;
7767 image_create_info.mipLevels = 1;
7768 image_create_info.arrayLayers = 1;
7769 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7770 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7771 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
7772 image_create_info.flags = 0;
7773 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7774 ASSERT_VK_SUCCESS(err);
7775 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
7776 ASSERT_VK_SUCCESS(err);
7778 VkMemoryRequirements memory_reqs;
7779 VkDeviceMemory image_memory;
7781 VkMemoryAllocateInfo memory_info = {};
7782 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7783 memory_info.pNext = NULL;
7784 memory_info.allocationSize = 0;
7785 memory_info.memoryTypeIndex = 0;
7786 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7787 // Allocate enough memory for both images
7788 memory_info.allocationSize = memory_reqs.size * 2;
7789 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7791 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7792 ASSERT_VK_SUCCESS(err);
7793 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7794 ASSERT_VK_SUCCESS(err);
7795 // Bind second image to memory right after first image
7796 err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
7797 ASSERT_VK_SUCCESS(err);
7799 VkImageViewCreateInfo image_view_create_info = {};
7800 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7801 image_view_create_info.image = image;
7802 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
7803 image_view_create_info.format = tex_format;
7804 image_view_create_info.subresourceRange.layerCount = 1;
7805 image_view_create_info.subresourceRange.baseMipLevel = 0;
7806 image_view_create_info.subresourceRange.levelCount = 1;
7807 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7811 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
7812 ASSERT_VK_SUCCESS(err);
7813 image_view_create_info.image = image2;
7814 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
7815 ASSERT_VK_SUCCESS(err);
7817 VkSamplerCreateInfo sampler_ci = {};
7818 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
7819 sampler_ci.pNext = NULL;
7820 sampler_ci.magFilter = VK_FILTER_NEAREST;
7821 sampler_ci.minFilter = VK_FILTER_NEAREST;
7822 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
7823 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7824 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7825 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7826 sampler_ci.mipLodBias = 1.0;
7827 sampler_ci.anisotropyEnable = VK_FALSE;
7828 sampler_ci.maxAnisotropy = 1;
7829 sampler_ci.compareEnable = VK_FALSE;
7830 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
7831 sampler_ci.minLod = 1.0;
7832 sampler_ci.maxLod = 1.0;
7833 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
7834 sampler_ci.unnormalizedCoordinates = VK_FALSE;
7837 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7838 ASSERT_VK_SUCCESS(err);
7839 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
7840 ASSERT_VK_SUCCESS(err);
7841 // Update descriptor with image and sampler
7842 VkDescriptorImageInfo img_info = {};
7843 img_info.sampler = sampler;
7844 img_info.imageView = view;
7845 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7847 VkWriteDescriptorSet descriptor_write;
7848 memset(&descriptor_write, 0, sizeof(descriptor_write));
7849 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7850 descriptor_write.dstSet = descriptorSet;
7851 descriptor_write.dstBinding = 0;
7852 descriptor_write.descriptorCount = 1;
7853 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7854 descriptor_write.pImageInfo = &img_info;
7856 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7858 // Create PSO to be used for draw-time errors below
7859 char const *vsSource = "#version 450\n"
7861 "out gl_PerVertex { \n"
7862 " vec4 gl_Position;\n"
7865 " gl_Position = vec4(1);\n"
7867 char const *fsSource = "#version 450\n"
7869 "layout(set=0, binding=0) uniform sampler2D s;\n"
7870 "layout(location=0) out vec4 x;\n"
7872 " x = texture(s, vec2(1));\n"
7874 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7875 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7876 VkPipelineObj pipe(m_device);
7877 pipe.AddShader(&vs);
7878 pipe.AddShader(&fs);
7879 pipe.AddColorAttachment();
7880 pipe.CreateVKPipeline(pipeline_layout, renderPass());
7882 // First error case is destroying sampler prior to cmd buffer submission
7883 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler ");
7884 BeginCommandBuffer();
7885 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7886 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7887 &descriptorSet, 0, NULL);
7890 // Destroy sampler invalidates the cmd buffer, causing error on submit
7891 vkDestroySampler(m_device->device(), sampler, NULL);
7892 // Attempt to submit cmd buffer
7893 VkSubmitInfo submit_info = {};
7894 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7895 submit_info.commandBufferCount = 1;
7896 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7897 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7898 m_errorMonitor->VerifyFound();
7899 // Now re-update descriptor with valid sampler and delete image
7900 img_info.sampler = sampler2;
7901 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7902 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7903 BeginCommandBuffer();
7904 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7905 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7906 &descriptorSet, 0, NULL);
7909 // Destroy image invalidates the cmd buffer, causing error on submit
7910 vkDestroyImage(m_device->device(), image, NULL);
7911 // Attempt to submit cmd buffer
7913 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7914 submit_info.commandBufferCount = 1;
7915 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7916 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7917 m_errorMonitor->VerifyFound();
7918 // Now update descriptor to be valid, but then free descriptor
7919 img_info.imageView = view2;
7920 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7921 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set ");
7922 BeginCommandBuffer();
7923 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7924 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7925 &descriptorSet, 0, NULL);
7928 // Destroy descriptor set invalidates the cb, causing error on submit
7929 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
7930 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
7931 m_errorMonitor->VerifyFound();
7932 // Attempt to submit cmd buffer
7934 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7935 submit_info.commandBufferCount = 1;
7936 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7937 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7938 m_errorMonitor->VerifyFound();
7940 vkFreeMemory(m_device->device(), image_memory, NULL);
7941 vkDestroySampler(m_device->device(), sampler2, NULL);
7942 vkDestroyImage(m_device->device(), image2, NULL);
7943 vkDestroyImageView(m_device->device(), view, NULL);
7944 vkDestroyImageView(m_device->device(), view2, NULL);
7945 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7946 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7947 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7950 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
7951 TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
7952 ASSERT_NO_FATAL_FAILURE(InitState());
7953 ASSERT_NO_FATAL_FAILURE(InitViewport());
7954 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7956 VkDescriptorPoolSize ds_type_count = {};
7957 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7958 ds_type_count.descriptorCount = 1;
7960 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7961 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7962 ds_pool_ci.pNext = NULL;
7963 ds_pool_ci.maxSets = 1;
7964 ds_pool_ci.poolSizeCount = 1;
7965 ds_pool_ci.pPoolSizes = &ds_type_count;
7967 VkDescriptorPool ds_pool;
7968 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7969 ASSERT_VK_SUCCESS(err);
7971 VkDescriptorSetLayoutBinding dsl_binding = {};
7972 dsl_binding.binding = 0;
7973 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7974 dsl_binding.descriptorCount = 1;
7975 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7976 dsl_binding.pImmutableSamplers = NULL;
7978 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7979 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7980 ds_layout_ci.pNext = NULL;
7981 ds_layout_ci.bindingCount = 1;
7982 ds_layout_ci.pBindings = &dsl_binding;
7983 VkDescriptorSetLayout ds_layout;
7984 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7985 ASSERT_VK_SUCCESS(err);
7987 VkDescriptorSet descriptorSet;
7988 VkDescriptorSetAllocateInfo alloc_info = {};
7989 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7990 alloc_info.descriptorSetCount = 1;
7991 alloc_info.descriptorPool = ds_pool;
7992 alloc_info.pSetLayouts = &ds_layout;
7993 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7994 ASSERT_VK_SUCCESS(err);
7996 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7997 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7998 pipeline_layout_ci.pNext = NULL;
7999 pipeline_layout_ci.setLayoutCount = 1;
8000 pipeline_layout_ci.pSetLayouts = &ds_layout;
8002 VkPipelineLayout pipeline_layout;
8003 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8004 ASSERT_VK_SUCCESS(err);
8006 // Create images to update the descriptor with
8008 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8009 const int32_t tex_width = 32;
8010 const int32_t tex_height = 32;
8011 VkImageCreateInfo image_create_info = {};
8012 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8013 image_create_info.pNext = NULL;
8014 image_create_info.imageType = VK_IMAGE_TYPE_2D;
8015 image_create_info.format = tex_format;
8016 image_create_info.extent.width = tex_width;
8017 image_create_info.extent.height = tex_height;
8018 image_create_info.extent.depth = 1;
8019 image_create_info.mipLevels = 1;
8020 image_create_info.arrayLayers = 1;
8021 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
8022 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
8023 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8024 image_create_info.flags = 0;
8025 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
8026 ASSERT_VK_SUCCESS(err);
8027 // Initially bind memory to avoid error at bind view time. We'll break binding before update.
8028 VkMemoryRequirements memory_reqs;
8029 VkDeviceMemory image_memory;
8031 VkMemoryAllocateInfo memory_info = {};
8032 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8033 memory_info.pNext = NULL;
8034 memory_info.allocationSize = 0;
8035 memory_info.memoryTypeIndex = 0;
8036 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
8037 // Allocate enough memory for image
8038 memory_info.allocationSize = memory_reqs.size;
8039 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
8041 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
8042 ASSERT_VK_SUCCESS(err);
8043 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
8044 ASSERT_VK_SUCCESS(err);
8046 VkImageViewCreateInfo image_view_create_info = {};
8047 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8048 image_view_create_info.image = image;
8049 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
8050 image_view_create_info.format = tex_format;
8051 image_view_create_info.subresourceRange.layerCount = 1;
8052 image_view_create_info.subresourceRange.baseMipLevel = 0;
8053 image_view_create_info.subresourceRange.levelCount = 1;
8054 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8057 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
8058 ASSERT_VK_SUCCESS(err);
8060 VkSamplerCreateInfo sampler_ci = {};
8061 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
8062 sampler_ci.pNext = NULL;
8063 sampler_ci.magFilter = VK_FILTER_NEAREST;
8064 sampler_ci.minFilter = VK_FILTER_NEAREST;
8065 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
8066 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8067 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8068 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8069 sampler_ci.mipLodBias = 1.0;
8070 sampler_ci.anisotropyEnable = VK_FALSE;
8071 sampler_ci.maxAnisotropy = 1;
8072 sampler_ci.compareEnable = VK_FALSE;
8073 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
8074 sampler_ci.minLod = 1.0;
8075 sampler_ci.maxLod = 1.0;
8076 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
8077 sampler_ci.unnormalizedCoordinates = VK_FALSE;
8079 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8080 ASSERT_VK_SUCCESS(err);
8081 // Update descriptor with image and sampler
8082 VkDescriptorImageInfo img_info = {};
8083 img_info.sampler = sampler;
8084 img_info.imageView = view;
8085 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8087 VkWriteDescriptorSet descriptor_write;
8088 memset(&descriptor_write, 0, sizeof(descriptor_write));
8089 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8090 descriptor_write.dstSet = descriptorSet;
8091 descriptor_write.dstBinding = 0;
8092 descriptor_write.descriptorCount = 1;
8093 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8094 descriptor_write.pImageInfo = &img_info;
8095 // Break memory binding and attempt update
8096 vkFreeMemory(m_device->device(), image_memory, nullptr);
8097 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8098 " previously bound memory was freed. Memory must not be freed prior to this operation.");
8099 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8100 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8101 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8102 m_errorMonitor->VerifyFound();
8104 vkDestroyImage(m_device->device(), image, NULL);
8105 vkDestroySampler(m_device->device(), sampler, NULL);
8106 vkDestroyImageView(m_device->device(), view, NULL);
8107 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8108 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8109 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8112 TEST_F(VkLayerTest, InvalidPipeline) {
8113 // Attempt to bind an invalid Pipeline to a valid Command Buffer
8114 // ObjectTracker should catch this.
8115 // Create a valid cmd buffer
8116 // call vkCmdBindPipeline w/ false Pipeline
8117 uint64_t fake_pipeline_handle = 0xbaad6001;
8118 VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
8119 ASSERT_NO_FATAL_FAILURE(InitState());
8120 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8122 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
8123 BeginCommandBuffer();
8124 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
8125 m_errorMonitor->VerifyFound();
8127 // Now issue a draw call with no pipeline bound
8128 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8130 m_errorMonitor->VerifyFound();
8132 // Finally same check once more but with Dispatch/Compute
8133 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8134 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
8135 vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
8136 m_errorMonitor->VerifyFound();
8139 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
8140 TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
8143 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
8145 ASSERT_NO_FATAL_FAILURE(InitState());
8146 ASSERT_NO_FATAL_FAILURE(InitViewport());
8147 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8148 VkDescriptorPoolSize ds_type_count = {};
8149 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8150 ds_type_count.descriptorCount = 1;
8152 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8153 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8154 ds_pool_ci.pNext = NULL;
8155 ds_pool_ci.maxSets = 1;
8156 ds_pool_ci.poolSizeCount = 1;
8157 ds_pool_ci.pPoolSizes = &ds_type_count;
8159 VkDescriptorPool ds_pool;
8160 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8161 ASSERT_VK_SUCCESS(err);
8163 VkDescriptorSetLayoutBinding dsl_binding = {};
8164 dsl_binding.binding = 0;
8165 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8166 dsl_binding.descriptorCount = 1;
8167 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8168 dsl_binding.pImmutableSamplers = NULL;
8170 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8171 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8172 ds_layout_ci.pNext = NULL;
8173 ds_layout_ci.bindingCount = 1;
8174 ds_layout_ci.pBindings = &dsl_binding;
8175 VkDescriptorSetLayout ds_layout;
8176 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8177 ASSERT_VK_SUCCESS(err);
8179 VkDescriptorSet descriptorSet;
8180 VkDescriptorSetAllocateInfo alloc_info = {};
8181 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8182 alloc_info.descriptorSetCount = 1;
8183 alloc_info.descriptorPool = ds_pool;
8184 alloc_info.pSetLayouts = &ds_layout;
8185 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8186 ASSERT_VK_SUCCESS(err);
8188 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8189 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8190 pipeline_layout_ci.pNext = NULL;
8191 pipeline_layout_ci.setLayoutCount = 1;
8192 pipeline_layout_ci.pSetLayouts = &ds_layout;
8194 VkPipelineLayout pipeline_layout;
8195 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8196 ASSERT_VK_SUCCESS(err);
8198 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8199 // We shouldn't need a fragment shader but add it to be able to run
8201 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8203 VkPipelineObj pipe(m_device);
8204 pipe.AddShader(&vs);
8205 pipe.AddShader(&fs);
8206 pipe.AddColorAttachment();
8207 pipe.CreateVKPipeline(pipeline_layout, renderPass());
8209 BeginCommandBuffer();
8210 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8211 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8212 &descriptorSet, 0, NULL);
8214 m_errorMonitor->VerifyFound();
8216 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8217 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8218 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8221 TEST_F(VkLayerTest, InvalidBufferViewObject) {
8222 // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
8225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer "
8226 "descriptor with invalid buffer view");
8228 ASSERT_NO_FATAL_FAILURE(InitState());
8229 VkDescriptorPoolSize ds_type_count = {};
8230 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8231 ds_type_count.descriptorCount = 1;
8233 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8234 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8235 ds_pool_ci.pNext = NULL;
8236 ds_pool_ci.maxSets = 1;
8237 ds_pool_ci.poolSizeCount = 1;
8238 ds_pool_ci.pPoolSizes = &ds_type_count;
8240 VkDescriptorPool ds_pool;
8241 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8242 ASSERT_VK_SUCCESS(err);
8244 VkDescriptorSetLayoutBinding dsl_binding = {};
8245 dsl_binding.binding = 0;
8246 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8247 dsl_binding.descriptorCount = 1;
8248 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8249 dsl_binding.pImmutableSamplers = NULL;
8251 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8252 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8253 ds_layout_ci.pNext = NULL;
8254 ds_layout_ci.bindingCount = 1;
8255 ds_layout_ci.pBindings = &dsl_binding;
8256 VkDescriptorSetLayout ds_layout;
8257 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8258 ASSERT_VK_SUCCESS(err);
8260 VkDescriptorSet descriptorSet;
8261 VkDescriptorSetAllocateInfo alloc_info = {};
8262 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8263 alloc_info.descriptorSetCount = 1;
8264 alloc_info.descriptorPool = ds_pool;
8265 alloc_info.pSetLayouts = &ds_layout;
8266 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8267 ASSERT_VK_SUCCESS(err);
8269 VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object
8270 VkWriteDescriptorSet descriptor_write;
8271 memset(&descriptor_write, 0, sizeof(descriptor_write));
8272 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8273 descriptor_write.dstSet = descriptorSet;
8274 descriptor_write.dstBinding = 0;
8275 descriptor_write.descriptorCount = 1;
8276 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8277 descriptor_write.pTexelBufferView = &view;
8279 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8281 m_errorMonitor->VerifyFound();
8283 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8284 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8287 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
8288 TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
8291 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8292 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8294 ASSERT_NO_FATAL_FAILURE(InitState());
8296 // Create a buffer with no bound memory and then attempt to create
8298 VkBufferCreateInfo buff_ci = {};
8299 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8300 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
8302 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8304 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
8305 ASSERT_VK_SUCCESS(err);
8307 VkBufferViewCreateInfo buff_view_ci = {};
8308 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8309 buff_view_ci.buffer = buffer;
8310 buff_view_ci.format = VK_FORMAT_R8_UNORM;
8311 buff_view_ci.range = VK_WHOLE_SIZE;
8312 VkBufferView buff_view;
8313 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
8315 m_errorMonitor->VerifyFound();
8316 vkDestroyBuffer(m_device->device(), buffer, NULL);
8317 // If last error is success, it still created the view, so delete it.
8318 if (err == VK_SUCCESS) {
8319 vkDestroyBufferView(m_device->device(), buff_view, NULL);
8323 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
8324 // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
8326 // 1. No dynamicOffset supplied
8327 // 2. Too many dynamicOffsets supplied
8328 // 3. Dynamic offset oversteps buffer being updated
8330 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only "
8331 "0 dynamicOffsets are left in "
8332 "pDynamicOffsets ");
8334 ASSERT_NO_FATAL_FAILURE(InitState());
8335 ASSERT_NO_FATAL_FAILURE(InitViewport());
8336 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8338 VkDescriptorPoolSize ds_type_count = {};
8339 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8340 ds_type_count.descriptorCount = 1;
8342 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8343 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8344 ds_pool_ci.pNext = NULL;
8345 ds_pool_ci.maxSets = 1;
8346 ds_pool_ci.poolSizeCount = 1;
8347 ds_pool_ci.pPoolSizes = &ds_type_count;
8349 VkDescriptorPool ds_pool;
8350 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8351 ASSERT_VK_SUCCESS(err);
8353 VkDescriptorSetLayoutBinding dsl_binding = {};
8354 dsl_binding.binding = 0;
8355 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8356 dsl_binding.descriptorCount = 1;
8357 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8358 dsl_binding.pImmutableSamplers = NULL;
8360 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8361 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8362 ds_layout_ci.pNext = NULL;
8363 ds_layout_ci.bindingCount = 1;
8364 ds_layout_ci.pBindings = &dsl_binding;
8365 VkDescriptorSetLayout ds_layout;
8366 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8367 ASSERT_VK_SUCCESS(err);
8369 VkDescriptorSet descriptorSet;
8370 VkDescriptorSetAllocateInfo alloc_info = {};
8371 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8372 alloc_info.descriptorSetCount = 1;
8373 alloc_info.descriptorPool = ds_pool;
8374 alloc_info.pSetLayouts = &ds_layout;
8375 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8376 ASSERT_VK_SUCCESS(err);
8378 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8379 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8380 pipeline_layout_ci.pNext = NULL;
8381 pipeline_layout_ci.setLayoutCount = 1;
8382 pipeline_layout_ci.pSetLayouts = &ds_layout;
8384 VkPipelineLayout pipeline_layout;
8385 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8386 ASSERT_VK_SUCCESS(err);
8388 // Create a buffer to update the descriptor with
8390 VkBufferCreateInfo buffCI = {};
8391 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8393 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8394 buffCI.queueFamilyIndexCount = 1;
8395 buffCI.pQueueFamilyIndices = &qfi;
8398 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8399 ASSERT_VK_SUCCESS(err);
8400 // Allocate memory and bind to buffer so we can make it to the appropriate
8402 VkMemoryAllocateInfo mem_alloc = {};
8403 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8404 mem_alloc.pNext = NULL;
8405 mem_alloc.allocationSize = 1024;
8406 mem_alloc.memoryTypeIndex = 0;
8408 VkMemoryRequirements memReqs;
8409 vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
8410 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
8412 vkDestroyBuffer(m_device->device(), dyub, NULL);
8417 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
8418 ASSERT_VK_SUCCESS(err);
8419 err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8420 ASSERT_VK_SUCCESS(err);
8421 // Correctly update descriptor to avoid "NOT_UPDATED" error
8422 VkDescriptorBufferInfo buffInfo = {};
8423 buffInfo.buffer = dyub;
8424 buffInfo.offset = 0;
8425 buffInfo.range = 1024;
8427 VkWriteDescriptorSet descriptor_write;
8428 memset(&descriptor_write, 0, sizeof(descriptor_write));
8429 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8430 descriptor_write.dstSet = descriptorSet;
8431 descriptor_write.dstBinding = 0;
8432 descriptor_write.descriptorCount = 1;
8433 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8434 descriptor_write.pBufferInfo = &buffInfo;
8436 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8438 BeginCommandBuffer();
8439 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8440 &descriptorSet, 0, NULL);
8441 m_errorMonitor->VerifyFound();
8442 uint32_t pDynOff[2] = {512, 756};
8443 // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
8444 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8445 "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
8446 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8447 &descriptorSet, 2, pDynOff);
8448 m_errorMonitor->VerifyFound();
8449 // Finally cause error due to dynamicOffset being too big
8450 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with "
8451 "offset 0 and range 1024 that "
8452 "oversteps the buffer size of 1024");
8453 // Create PSO to be used for draw-time errors below
8454 char const *vsSource = "#version 450\n"
8456 "out gl_PerVertex { \n"
8457 " vec4 gl_Position;\n"
8460 " gl_Position = vec4(1);\n"
8462 char const *fsSource = "#version 450\n"
8464 "layout(location=0) out vec4 x;\n"
8465 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8467 " x = vec4(bar.y);\n"
8469 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8470 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8471 VkPipelineObj pipe(m_device);
8472 pipe.AddShader(&vs);
8473 pipe.AddShader(&fs);
8474 pipe.AddColorAttachment();
8475 pipe.CreateVKPipeline(pipeline_layout, renderPass());
8477 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8478 // This update should succeed, but offset size of 512 will overstep buffer
8479 // /w range 1024 & size 1024
8480 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8481 &descriptorSet, 1, pDynOff);
8483 m_errorMonitor->VerifyFound();
8485 vkDestroyBuffer(m_device->device(), dyub, NULL);
8486 vkFreeMemory(m_device->device(), mem, NULL);
8488 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8489 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8490 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8493 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
8494 TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
8495 "that doesn't have memory bound");
8497 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8498 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8499 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8500 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8502 ASSERT_NO_FATAL_FAILURE(InitState());
8503 ASSERT_NO_FATAL_FAILURE(InitViewport());
8504 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8506 VkDescriptorPoolSize ds_type_count = {};
8507 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8508 ds_type_count.descriptorCount = 1;
8510 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8511 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8512 ds_pool_ci.pNext = NULL;
8513 ds_pool_ci.maxSets = 1;
8514 ds_pool_ci.poolSizeCount = 1;
8515 ds_pool_ci.pPoolSizes = &ds_type_count;
8517 VkDescriptorPool ds_pool;
8518 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8519 ASSERT_VK_SUCCESS(err);
8521 VkDescriptorSetLayoutBinding dsl_binding = {};
8522 dsl_binding.binding = 0;
8523 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8524 dsl_binding.descriptorCount = 1;
8525 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8526 dsl_binding.pImmutableSamplers = NULL;
8528 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8529 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8530 ds_layout_ci.pNext = NULL;
8531 ds_layout_ci.bindingCount = 1;
8532 ds_layout_ci.pBindings = &dsl_binding;
8533 VkDescriptorSetLayout ds_layout;
8534 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8535 ASSERT_VK_SUCCESS(err);
8537 VkDescriptorSet descriptorSet;
8538 VkDescriptorSetAllocateInfo alloc_info = {};
8539 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8540 alloc_info.descriptorSetCount = 1;
8541 alloc_info.descriptorPool = ds_pool;
8542 alloc_info.pSetLayouts = &ds_layout;
8543 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8544 ASSERT_VK_SUCCESS(err);
8546 // Create a buffer to update the descriptor with
8548 VkBufferCreateInfo buffCI = {};
8549 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8551 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8552 buffCI.queueFamilyIndexCount = 1;
8553 buffCI.pQueueFamilyIndices = &qfi;
8556 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8557 ASSERT_VK_SUCCESS(err);
8559 // Attempt to update descriptor without binding memory to it
8560 VkDescriptorBufferInfo buffInfo = {};
8561 buffInfo.buffer = dyub;
8562 buffInfo.offset = 0;
8563 buffInfo.range = 1024;
8565 VkWriteDescriptorSet descriptor_write;
8566 memset(&descriptor_write, 0, sizeof(descriptor_write));
8567 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8568 descriptor_write.dstSet = descriptorSet;
8569 descriptor_write.dstBinding = 0;
8570 descriptor_write.descriptorCount = 1;
8571 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8572 descriptor_write.pBufferInfo = &buffInfo;
8574 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8575 m_errorMonitor->VerifyFound();
8577 vkDestroyBuffer(m_device->device(), dyub, NULL);
8578 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8579 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8582 TEST_F(VkLayerTest, InvalidPushConstants) {
8584 ASSERT_NO_FATAL_FAILURE(InitState());
8585 ASSERT_NO_FATAL_FAILURE(InitViewport());
8586 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8588 VkPipelineLayout pipeline_layout;
8589 VkPushConstantRange pc_range = {};
8590 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8591 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8592 pipeline_layout_ci.pushConstantRangeCount = 1;
8593 pipeline_layout_ci.pPushConstantRanges = &pc_range;
8596 // Check for invalid push constant ranges in pipeline layouts.
8598 struct PipelineLayoutTestCase {
8599 VkPushConstantRange const range;
8603 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
8604 const std::array<PipelineLayoutTestCase, 10> range_tests = {{
8605 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
8606 "vkCreatePipelineLayout() call has push constants index 0 with "
8608 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8609 "vkCreatePipelineLayout() call has push constants index 0 with "
8611 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8612 "vkCreatePipelineLayout() call has push constants index 0 with "
8614 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
8615 "vkCreatePipelineLayout() call has push constants index 0 with "
8617 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8618 "vkCreatePipelineLayout() call has push constants index 0 with "
8619 "offset 1. Offset must"},
8620 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big},
8621 "vkCreatePipelineLayout() call has push constants index 0 "
8623 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
8624 "vkCreatePipelineLayout() call has push constants "
8625 "index 0 with offset "},
8626 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
8627 "vkCreatePipelineLayout() call has push constants index 0 "
8629 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
8630 "vkCreatePipelineLayout() call has push "
8631 "constants index 0 with offset "},
8632 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
8633 "vkCreatePipelineLayout() call has push "
8634 "constants index 0 with offset "},
8637 // Check for invalid offset and size
8638 for (const auto &iter : range_tests) {
8639 pc_range = iter.range;
8640 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8641 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8642 m_errorMonitor->VerifyFound();
8643 if (VK_SUCCESS == err) {
8644 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8648 // Check for invalid stage flag
8649 pc_range.offset = 0;
8651 pc_range.stageFlags = 0;
8652 m_errorMonitor->SetDesiredFailureMsg(
8653 VK_DEBUG_REPORT_ERROR_BIT_EXT,
8654 "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
8655 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8656 m_errorMonitor->VerifyFound();
8657 if (VK_SUCCESS == err) {
8658 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8661 // Check for overlapping ranges
8662 const uint32_t ranges_per_test = 5;
8663 struct OverlappingRangeTestCase {
8664 VkPushConstantRange const ranges[ranges_per_test];
8668 const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = {
8669 {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8670 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8671 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8672 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8673 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8674 "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
8676 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8677 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8678 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8679 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8680 {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8681 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
8684 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8685 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8686 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8687 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8688 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8689 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
8692 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8693 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8694 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8695 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8696 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8697 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
8700 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8701 {VK_SHADER_STAGE_VERTEX_BIT, 32, 4},
8702 {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
8703 {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
8704 {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
8705 "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
8708 for (const auto &iter : overlapping_range_tests) {
8709 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8710 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
8711 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg);
8712 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8713 m_errorMonitor->VerifyFound();
8714 if (VK_SUCCESS == err) {
8715 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8719 // Run some positive tests to make sure overlap checking in the layer is OK
8720 const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8721 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8722 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8723 {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
8724 {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8726 {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
8727 {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
8728 {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
8729 {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
8730 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8732 for (const auto &iter : overlapping_range_tests_pos) {
8733 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8734 m_errorMonitor->ExpectSuccess();
8735 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8736 m_errorMonitor->VerifyNotFound();
8737 if (VK_SUCCESS == err) {
8738 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8743 // CmdPushConstants tests
8745 const uint8_t dummy_values[100] = {};
8747 // Check for invalid offset and size and if range is within layout range(s)
8748 const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
8749 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
8750 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8751 "vkCmdPushConstants() call has push constants with size 1. Size "
8752 "must be greater than zero and a multiple of 4."},
8753 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8754 "vkCmdPushConstants() call has push constants with size 1. Size "
8755 "must be greater than zero and a multiple of 4."},
8756 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8757 "vkCmdPushConstants() call has push constants with offset 1. "
8758 "Offset must be a multiple of 4."},
8759 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8760 "vkCmdPushConstants() call has push constants with offset 1. "
8761 "Offset must be a multiple of 4."},
8762 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8763 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8764 "0x1 not within flag-matching ranges in pipeline layout"},
8765 {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8},
8766 "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = "
8767 "0x1 not within flag-matching ranges in pipeline layout"},
8768 {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8},
8769 "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = "
8770 "0x1 not within flag-matching ranges in pipeline layout"},
8771 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80},
8772 "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = "
8773 "0x1 not within flag-matching ranges in pipeline layout"},
8774 {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
8775 "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in "
8776 "any of the ranges in pipeline layout"},
8777 {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
8778 "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
8779 "any of the ranges in pipeline layout"},
8782 BeginCommandBuffer();
8784 // Setup ranges: [0,16) [64,80)
8785 const VkPushConstantRange pc_range2[] = {
8786 {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
8788 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange);
8789 pipeline_layout_ci.pPushConstantRanges = pc_range2;
8790 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8791 ASSERT_VK_SUCCESS(err);
8792 for (const auto &iter : cmd_range_tests) {
8793 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8794 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8795 iter.range.size, dummy_values);
8796 m_errorMonitor->VerifyFound();
8799 // Check for invalid stage flag
8800 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
8801 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
8802 m_errorMonitor->VerifyFound();
8803 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8805 // overlapping range tests with cmd
8806 const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{
8807 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8808 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8809 "0x1 not within flag-matching ranges in pipeline layout"},
8810 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8811 "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = "
8812 "0x1 not within flag-matching ranges in pipeline layout"},
8813 {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16},
8814 "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
8815 "0x1 not within flag-matching ranges in pipeline layout"},
8817 // Setup ranges: [0,16), [20,36), [36,44), [44,52), [80,92)
8818 const VkPushConstantRange pc_range3[] = {
8819 {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8820 {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
8822 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
8823 pipeline_layout_ci.pPushConstantRanges = pc_range3;
8824 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8825 ASSERT_VK_SUCCESS(err);
8826 for (const auto &iter : cmd_overlap_tests) {
8827 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8828 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8829 iter.range.size, dummy_values);
8830 m_errorMonitor->VerifyFound();
8832 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8834 // positive overlapping range tests with cmd
8835 const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
8836 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
8837 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
8838 {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
8839 {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
8841 // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
8842 const VkPushConstantRange pc_range4[] = {
8843 {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8844 {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 24},
8846 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
8847 pipeline_layout_ci.pPushConstantRanges = pc_range4;
8848 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8849 ASSERT_VK_SUCCESS(err);
8850 for (const auto &iter : cmd_overlap_tests_pos) {
8851 m_errorMonitor->ExpectSuccess();
8852 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8853 iter.range.size, dummy_values);
8854 m_errorMonitor->VerifyNotFound();
8856 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8861 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
8862 // Test various desriptorSet errors with bad binding combinations
8865 ASSERT_NO_FATAL_FAILURE(InitState());
8866 ASSERT_NO_FATAL_FAILURE(InitViewport());
8867 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8869 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
8870 VkImageTiling tiling;
8871 VkFormatProperties format_properties;
8872 vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
8873 if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8874 tiling = VK_IMAGE_TILING_LINEAR;
8875 } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8876 tiling = VK_IMAGE_TILING_OPTIMAL;
8878 printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
8883 static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
8884 VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
8885 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8886 ds_type_count[0].descriptorCount = 10;
8887 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8888 ds_type_count[1].descriptorCount = 2;
8889 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8890 ds_type_count[2].descriptorCount = 2;
8891 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
8892 ds_type_count[3].descriptorCount = 5;
8893 // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
8895 // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
8896 ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8897 ds_type_count[4].descriptorCount = 2;
8899 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8900 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8901 ds_pool_ci.pNext = NULL;
8902 ds_pool_ci.maxSets = 5;
8903 ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
8904 ds_pool_ci.pPoolSizes = ds_type_count;
8906 VkDescriptorPool ds_pool;
8907 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8908 ASSERT_VK_SUCCESS(err);
8910 static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
8911 VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
8912 dsl_binding[0].binding = 0;
8913 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8914 dsl_binding[0].descriptorCount = 5;
8915 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
8916 dsl_binding[0].pImmutableSamplers = NULL;
8918 // Create layout identical to set0 layout but w/ different stageFlags
8919 VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
8920 dsl_fs_stage_only.binding = 0;
8921 dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8922 dsl_fs_stage_only.descriptorCount = 5;
8923 dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at
8925 dsl_fs_stage_only.pImmutableSamplers = NULL;
8926 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8927 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8928 ds_layout_ci.pNext = NULL;
8929 ds_layout_ci.bindingCount = 1;
8930 ds_layout_ci.pBindings = dsl_binding;
8931 static const uint32_t NUM_LAYOUTS = 4;
8932 VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {};
8933 VkDescriptorSetLayout ds_layout_fs_only = {};
8934 // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
8935 // layout for error case
8936 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]);
8937 ASSERT_VK_SUCCESS(err);
8938 ds_layout_ci.pBindings = &dsl_fs_stage_only;
8939 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only);
8940 ASSERT_VK_SUCCESS(err);
8941 dsl_binding[0].binding = 0;
8942 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8943 dsl_binding[0].descriptorCount = 2;
8944 dsl_binding[1].binding = 1;
8945 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8946 dsl_binding[1].descriptorCount = 2;
8947 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
8948 dsl_binding[1].pImmutableSamplers = NULL;
8949 ds_layout_ci.pBindings = dsl_binding;
8950 ds_layout_ci.bindingCount = 2;
8951 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]);
8952 ASSERT_VK_SUCCESS(err);
8953 dsl_binding[0].binding = 0;
8954 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8955 dsl_binding[0].descriptorCount = 5;
8956 ds_layout_ci.bindingCount = 1;
8957 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]);
8958 ASSERT_VK_SUCCESS(err);
8959 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8960 dsl_binding[0].descriptorCount = 2;
8961 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]);
8962 ASSERT_VK_SUCCESS(err);
8964 static const uint32_t NUM_SETS = 4;
8965 VkDescriptorSet descriptorSet[NUM_SETS] = {};
8966 VkDescriptorSetAllocateInfo alloc_info = {};
8967 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8968 alloc_info.descriptorSetCount = NUM_LAYOUTS;
8969 alloc_info.descriptorPool = ds_pool;
8970 alloc_info.pSetLayouts = ds_layout;
8971 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
8972 ASSERT_VK_SUCCESS(err);
8973 VkDescriptorSet ds0_fs_only = {};
8974 alloc_info.descriptorSetCount = 1;
8975 alloc_info.pSetLayouts = &ds_layout_fs_only;
8976 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
8977 ASSERT_VK_SUCCESS(err);
8979 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8980 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8981 pipeline_layout_ci.pNext = NULL;
8982 pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS;
8983 pipeline_layout_ci.pSetLayouts = ds_layout;
8985 VkPipelineLayout pipeline_layout;
8986 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8987 ASSERT_VK_SUCCESS(err);
8988 // Create pipelineLayout with only one setLayout
8989 pipeline_layout_ci.setLayoutCount = 1;
8990 VkPipelineLayout single_pipe_layout;
8991 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout);
8992 ASSERT_VK_SUCCESS(err);
8993 // Create pipelineLayout with 2 descriptor setLayout at index 0
8994 pipeline_layout_ci.pSetLayouts = &ds_layout[3];
8995 VkPipelineLayout pipe_layout_one_desc;
8996 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc);
8997 ASSERT_VK_SUCCESS(err);
8998 // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
8999 pipeline_layout_ci.pSetLayouts = &ds_layout[2];
9000 VkPipelineLayout pipe_layout_five_samp;
9001 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp);
9002 ASSERT_VK_SUCCESS(err);
9003 // Create pipelineLayout with UB type, but stageFlags for FS only
9004 pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only;
9005 VkPipelineLayout pipe_layout_fs_only;
9006 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only);
9007 ASSERT_VK_SUCCESS(err);
9008 // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
9009 VkDescriptorSetLayout pl_bad_s0[2] = {};
9010 pl_bad_s0[0] = ds_layout_fs_only;
9011 pl_bad_s0[1] = ds_layout[1];
9012 pipeline_layout_ci.setLayoutCount = 2;
9013 pipeline_layout_ci.pSetLayouts = pl_bad_s0;
9014 VkPipelineLayout pipe_layout_bad_set0;
9015 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0);
9016 ASSERT_VK_SUCCESS(err);
9018 // Create a buffer to update the descriptor with
9020 VkBufferCreateInfo buffCI = {};
9021 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9023 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
9024 buffCI.queueFamilyIndexCount = 1;
9025 buffCI.pQueueFamilyIndices = &qfi;
9028 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
9029 ASSERT_VK_SUCCESS(err);
9030 // Correctly update descriptor to avoid "NOT_UPDATED" error
9031 static const uint32_t NUM_BUFFS = 5;
9032 VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {};
9033 for (uint32_t i = 0; i < NUM_BUFFS; ++i) {
9034 buffInfo[i].buffer = dyub;
9035 buffInfo[i].offset = 0;
9036 buffInfo[i].range = 1024;
9039 const int32_t tex_width = 32;
9040 const int32_t tex_height = 32;
9041 VkImageCreateInfo image_create_info = {};
9042 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9043 image_create_info.pNext = NULL;
9044 image_create_info.imageType = VK_IMAGE_TYPE_2D;
9045 image_create_info.format = tex_format;
9046 image_create_info.extent.width = tex_width;
9047 image_create_info.extent.height = tex_height;
9048 image_create_info.extent.depth = 1;
9049 image_create_info.mipLevels = 1;
9050 image_create_info.arrayLayers = 1;
9051 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9052 image_create_info.tiling = tiling;
9053 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
9054 image_create_info.flags = 0;
9055 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9056 ASSERT_VK_SUCCESS(err);
9058 VkMemoryRequirements memReqs;
9059 VkDeviceMemory imageMem;
9061 VkMemoryAllocateInfo memAlloc = {};
9062 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9063 memAlloc.pNext = NULL;
9064 memAlloc.allocationSize = 0;
9065 memAlloc.memoryTypeIndex = 0;
9066 vkGetImageMemoryRequirements(m_device->device(), image, &memReqs);
9067 memAlloc.allocationSize = memReqs.size;
9068 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
9070 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem);
9071 ASSERT_VK_SUCCESS(err);
9072 err = vkBindImageMemory(m_device->device(), image, imageMem, 0);
9073 ASSERT_VK_SUCCESS(err);
9075 VkImageViewCreateInfo image_view_create_info = {};
9076 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
9077 image_view_create_info.image = image;
9078 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
9079 image_view_create_info.format = tex_format;
9080 image_view_create_info.subresourceRange.layerCount = 1;
9081 image_view_create_info.subresourceRange.baseMipLevel = 0;
9082 image_view_create_info.subresourceRange.levelCount = 1;
9083 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9086 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
9087 ASSERT_VK_SUCCESS(err);
9088 VkDescriptorImageInfo imageInfo[4] = {};
9089 imageInfo[0].imageView = view;
9090 imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9091 imageInfo[1].imageView = view;
9092 imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9093 imageInfo[2].imageView = view;
9094 imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9095 imageInfo[3].imageView = view;
9096 imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9098 static const uint32_t NUM_SET_UPDATES = 3;
9099 VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
9100 descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9101 descriptor_write[0].dstSet = descriptorSet[0];
9102 descriptor_write[0].dstBinding = 0;
9103 descriptor_write[0].descriptorCount = 5;
9104 descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9105 descriptor_write[0].pBufferInfo = buffInfo;
9106 descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9107 descriptor_write[1].dstSet = descriptorSet[1];
9108 descriptor_write[1].dstBinding = 0;
9109 descriptor_write[1].descriptorCount = 2;
9110 descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9111 descriptor_write[1].pImageInfo = imageInfo;
9112 descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9113 descriptor_write[2].dstSet = descriptorSet[1];
9114 descriptor_write[2].dstBinding = 1;
9115 descriptor_write[2].descriptorCount = 2;
9116 descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9117 descriptor_write[2].pImageInfo = &imageInfo[2];
9119 vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL);
9121 // Create PSO to be used for draw-time errors below
9122 char const *vsSource = "#version 450\n"
9124 "out gl_PerVertex {\n"
9125 " vec4 gl_Position;\n"
9128 " gl_Position = vec4(1);\n"
9130 char const *fsSource = "#version 450\n"
9132 "layout(location=0) out vec4 x;\n"
9133 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
9135 " x = vec4(bar.y);\n"
9137 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9138 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9139 VkPipelineObj pipe(m_device);
9140 pipe.AddShader(&vs);
9141 pipe.AddShader(&fs);
9142 pipe.AddColorAttachment();
9143 pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass());
9145 BeginCommandBuffer();
9147 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9148 // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
9150 // here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
9152 // due to the fact that cmd_alloc_dset_data() has not been called in
9153 // cmd_bind_graphics_pipeline()
9154 // TODO : Want to cause various binding incompatibility issues here to test
9156 // First cause various verify_layout_compatibility() fails
9157 // Second disturb early and late sets and verify INFO msgs
9158 // verify_set_layout_compatibility fail cases:
9159 // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
9160 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object ");
9161 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
9162 (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL);
9163 m_errorMonitor->VerifyFound();
9165 // 2. layoutIndex exceeds # of layouts in layout
9166 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
9167 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2,
9168 &descriptorSet[0], 0, NULL);
9169 m_errorMonitor->VerifyFound();
9171 vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL);
9172 // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
9174 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
9175 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1,
9176 &descriptorSet[0], 0, NULL);
9177 m_errorMonitor->VerifyFound();
9179 vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL);
9180 // 4. same # of descriptors but mismatch in type
9181 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
9182 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1,
9183 &descriptorSet[0], 0, NULL);
9184 m_errorMonitor->VerifyFound();
9186 vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL);
9187 // 5. same # of descriptors but mismatch in stageFlags
9188 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9189 " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
9190 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9191 &descriptorSet[0], 0, NULL);
9192 m_errorMonitor->VerifyFound();
9194 // Cause INFO messages due to disturbing previously bound Sets
9195 // First bind sets 0 & 1
9196 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9197 &descriptorSet[0], 0, NULL);
9198 // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout
9199 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed ");
9200 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9201 &descriptorSet[1], 0, NULL);
9202 m_errorMonitor->VerifyFound();
9204 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9205 &descriptorSet[0], 0, NULL);
9206 // 2. Disturb set after last bound set
9207 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and "
9208 "any subsequent sets were disturbed ");
9209 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9210 &ds0_fs_only, 0, NULL);
9211 m_errorMonitor->VerifyFound();
9213 // Now that we're done actively using the pipelineLayout that gfx pipeline
9214 // was created with, we should be able to delete it. Do that now to verify
9215 // that validation obeys pipelineLayout lifetime
9216 vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
9218 // Cause draw-time errors due to PSO incompatibilities
9219 // 1. Error due to not binding required set (we actually use same code as
9220 // above to disturb set0)
9221 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9222 &descriptorSet[0], 0, NULL);
9223 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9224 &descriptorSet[1], 0, NULL);
9225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
9227 m_errorMonitor->VerifyFound();
9229 vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL);
9230 // 2. Error due to bound set not being compatible with PSO's
9231 // VkPipelineLayout (diff stageFlags in this case)
9232 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9233 &descriptorSet[0], 0, NULL);
9234 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
9236 m_errorMonitor->VerifyFound();
9238 // Remaining clean-up
9239 for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
9240 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
9242 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
9243 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
9244 vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
9245 vkDestroyBuffer(m_device->device(), dyub, NULL);
9246 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9247 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9248 vkFreeMemory(m_device->device(), imageMem, NULL);
9249 vkDestroyImage(m_device->device(), image, NULL);
9250 vkDestroyImageView(m_device->device(), view, NULL);
9253 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
9255 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9256 "You must call vkBeginCommandBuffer() before this call to ");
9258 ASSERT_NO_FATAL_FAILURE(InitState());
9259 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9260 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
9261 vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9263 m_errorMonitor->VerifyFound();
9266 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
9268 VkCommandBuffer draw_cmd;
9270 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter.");
9272 ASSERT_NO_FATAL_FAILURE(InitState());
9274 VkCommandBufferAllocateInfo cmd = {};
9275 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
9277 cmd.commandPool = m_commandPool;
9278 cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
9279 cmd.commandBufferCount = 1;
9281 err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd);
9282 ASSERT_VK_SUCCESS(err);
9284 // Force the failure by not setting the Renderpass and Framebuffer fields
9285 VkCommandBufferBeginInfo cmd_buf_info = {};
9286 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9287 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9288 cmd_buf_info.pNext = NULL;
9289 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
9290 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9292 // The error should be caught by validation of the BeginCommandBuffer call
9293 vkBeginCommandBuffer(draw_cmd, &cmd_buf_info);
9295 m_errorMonitor->VerifyFound();
9296 vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd);
9299 TEST_F(VkLayerTest, CommandBufferResetErrors) {
9300 // Cause error due to Begin while recording CB
9301 // Then cause 2 errors for attempting to reset CB w/o having
9302 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
9303 // which CBs were allocated. Note that this bit is off by default.
9304 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
9306 ASSERT_NO_FATAL_FAILURE(InitState());
9308 // Calls AllocateCommandBuffers
9309 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9311 // Force the failure by setting the Renderpass and Framebuffer fields with
9313 VkCommandBufferBeginInfo cmd_buf_info = {};
9314 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9315 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9316 cmd_buf_info.pNext = NULL;
9317 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
9318 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9320 // Begin CB to transition to recording state
9321 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9322 // Can't re-begin. This should trigger error
9323 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9324 m_errorMonitor->VerifyFound();
9326 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer ");
9327 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
9328 // Reset attempt will trigger error due to incorrect CommandPool state
9329 vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags);
9330 m_errorMonitor->VerifyFound();
9332 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from ");
9333 // Transition CB to RECORDED state
9334 vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9335 // Now attempting to Begin will implicitly reset, which triggers error
9336 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9337 m_errorMonitor->VerifyFound();
9340 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
9341 // Attempt to Create Gfx Pipeline w/o a VS
9344 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
9346 ASSERT_NO_FATAL_FAILURE(InitState());
9347 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9349 VkDescriptorPoolSize ds_type_count = {};
9350 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9351 ds_type_count.descriptorCount = 1;
9353 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9354 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9355 ds_pool_ci.pNext = NULL;
9356 ds_pool_ci.maxSets = 1;
9357 ds_pool_ci.poolSizeCount = 1;
9358 ds_pool_ci.pPoolSizes = &ds_type_count;
9360 VkDescriptorPool ds_pool;
9361 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9362 ASSERT_VK_SUCCESS(err);
9364 VkDescriptorSetLayoutBinding dsl_binding = {};
9365 dsl_binding.binding = 0;
9366 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9367 dsl_binding.descriptorCount = 1;
9368 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9369 dsl_binding.pImmutableSamplers = NULL;
9371 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9372 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9373 ds_layout_ci.pNext = NULL;
9374 ds_layout_ci.bindingCount = 1;
9375 ds_layout_ci.pBindings = &dsl_binding;
9377 VkDescriptorSetLayout ds_layout;
9378 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9379 ASSERT_VK_SUCCESS(err);
9381 VkDescriptorSet descriptorSet;
9382 VkDescriptorSetAllocateInfo alloc_info = {};
9383 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9384 alloc_info.descriptorSetCount = 1;
9385 alloc_info.descriptorPool = ds_pool;
9386 alloc_info.pSetLayouts = &ds_layout;
9387 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9388 ASSERT_VK_SUCCESS(err);
9390 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9391 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9392 pipeline_layout_ci.setLayoutCount = 1;
9393 pipeline_layout_ci.pSetLayouts = &ds_layout;
9395 VkPipelineLayout pipeline_layout;
9396 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9397 ASSERT_VK_SUCCESS(err);
9399 VkViewport vp = {}; // Just need dummy vp to point to
9400 VkRect2D sc = {}; // dummy scissor to point to
9402 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9403 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9404 vp_state_ci.scissorCount = 1;
9405 vp_state_ci.pScissors = ≻
9406 vp_state_ci.viewportCount = 1;
9407 vp_state_ci.pViewports = &vp;
9409 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9410 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9411 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9412 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9413 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9414 rs_state_ci.depthClampEnable = VK_FALSE;
9415 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9416 rs_state_ci.depthBiasEnable = VK_FALSE;
9418 VkGraphicsPipelineCreateInfo gp_ci = {};
9419 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9420 gp_ci.pViewportState = &vp_state_ci;
9421 gp_ci.pRasterizationState = &rs_state_ci;
9422 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9423 gp_ci.layout = pipeline_layout;
9424 gp_ci.renderPass = renderPass();
9426 VkPipelineCacheCreateInfo pc_ci = {};
9427 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9428 pc_ci.initialDataSize = 0;
9429 pc_ci.pInitialData = 0;
9431 VkPipeline pipeline;
9432 VkPipelineCache pipelineCache;
9434 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9435 ASSERT_VK_SUCCESS(err);
9436 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9438 m_errorMonitor->VerifyFound();
9440 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9441 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9442 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9443 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9445 /*// TODO : This test should be good, but needs Tess support in compiler to run
9446 TEST_F(VkLayerTest, InvalidPatchControlPoints)
9448 // Attempt to Create Gfx Pipeline w/o a VS
9451 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9452 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
9455 ASSERT_NO_FATAL_FAILURE(InitState());
9456 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9458 VkDescriptorPoolSize ds_type_count = {};
9459 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9460 ds_type_count.descriptorCount = 1;
9462 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9463 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9464 ds_pool_ci.pNext = NULL;
9465 ds_pool_ci.poolSizeCount = 1;
9466 ds_pool_ci.pPoolSizes = &ds_type_count;
9468 VkDescriptorPool ds_pool;
9469 err = vkCreateDescriptorPool(m_device->device(),
9470 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
9471 ASSERT_VK_SUCCESS(err);
9473 VkDescriptorSetLayoutBinding dsl_binding = {};
9474 dsl_binding.binding = 0;
9475 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9476 dsl_binding.descriptorCount = 1;
9477 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9478 dsl_binding.pImmutableSamplers = NULL;
9480 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9481 ds_layout_ci.sType =
9482 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9483 ds_layout_ci.pNext = NULL;
9484 ds_layout_ci.bindingCount = 1;
9485 ds_layout_ci.pBindings = &dsl_binding;
9487 VkDescriptorSetLayout ds_layout;
9488 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
9490 ASSERT_VK_SUCCESS(err);
9492 VkDescriptorSet descriptorSet;
9493 err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
9494 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
9495 ASSERT_VK_SUCCESS(err);
9497 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9498 pipeline_layout_ci.sType =
9499 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9500 pipeline_layout_ci.pNext = NULL;
9501 pipeline_layout_ci.setLayoutCount = 1;
9502 pipeline_layout_ci.pSetLayouts = &ds_layout;
9504 VkPipelineLayout pipeline_layout;
9505 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
9507 ASSERT_VK_SUCCESS(err);
9509 VkPipelineShaderStageCreateInfo shaderStages[3];
9510 memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
9512 VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
9514 // Just using VS txt for Tess shaders as we don't care about functionality
9516 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9519 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9522 shaderStages[0].sType =
9523 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9524 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
9525 shaderStages[0].shader = vs.handle();
9526 shaderStages[1].sType =
9527 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9528 shaderStages[1].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
9529 shaderStages[1].shader = tc.handle();
9530 shaderStages[2].sType =
9531 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9532 shaderStages[2].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
9533 shaderStages[2].shader = te.handle();
9535 VkPipelineInputAssemblyStateCreateInfo iaCI = {};
9537 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9538 iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
9540 VkPipelineTessellationStateCreateInfo tsCI = {};
9541 tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
9542 tsCI.patchControlPoints = 0; // This will cause an error
9544 VkGraphicsPipelineCreateInfo gp_ci = {};
9545 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9547 gp_ci.stageCount = 3;
9548 gp_ci.pStages = shaderStages;
9549 gp_ci.pVertexInputState = NULL;
9550 gp_ci.pInputAssemblyState = &iaCI;
9551 gp_ci.pTessellationState = &tsCI;
9552 gp_ci.pViewportState = NULL;
9553 gp_ci.pRasterizationState = NULL;
9554 gp_ci.pMultisampleState = NULL;
9555 gp_ci.pDepthStencilState = NULL;
9556 gp_ci.pColorBlendState = NULL;
9557 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9558 gp_ci.layout = pipeline_layout;
9559 gp_ci.renderPass = renderPass();
9561 VkPipelineCacheCreateInfo pc_ci = {};
9562 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9564 pc_ci.initialSize = 0;
9565 pc_ci.initialData = 0;
9568 VkPipeline pipeline;
9569 VkPipelineCache pipelineCache;
9571 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
9573 ASSERT_VK_SUCCESS(err);
9574 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
9575 &gp_ci, NULL, &pipeline);
9577 m_errorMonitor->VerifyFound();
9579 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9580 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9581 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9582 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9585 // Set scissor and viewport counts to different numbers
9586 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) {
9589 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9590 "Gfx Pipeline viewport count (1) must match scissor count (0).");
9592 ASSERT_NO_FATAL_FAILURE(InitState());
9593 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9595 VkDescriptorPoolSize ds_type_count = {};
9596 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9597 ds_type_count.descriptorCount = 1;
9599 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9600 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9601 ds_pool_ci.maxSets = 1;
9602 ds_pool_ci.poolSizeCount = 1;
9603 ds_pool_ci.pPoolSizes = &ds_type_count;
9605 VkDescriptorPool ds_pool;
9606 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9607 ASSERT_VK_SUCCESS(err);
9609 VkDescriptorSetLayoutBinding dsl_binding = {};
9610 dsl_binding.binding = 0;
9611 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9612 dsl_binding.descriptorCount = 1;
9613 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9615 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9616 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9617 ds_layout_ci.bindingCount = 1;
9618 ds_layout_ci.pBindings = &dsl_binding;
9620 VkDescriptorSetLayout ds_layout;
9621 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9622 ASSERT_VK_SUCCESS(err);
9624 VkDescriptorSet descriptorSet;
9625 VkDescriptorSetAllocateInfo alloc_info = {};
9626 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9627 alloc_info.descriptorSetCount = 1;
9628 alloc_info.descriptorPool = ds_pool;
9629 alloc_info.pSetLayouts = &ds_layout;
9630 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9631 ASSERT_VK_SUCCESS(err);
9633 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9634 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9635 pipeline_layout_ci.setLayoutCount = 1;
9636 pipeline_layout_ci.pSetLayouts = &ds_layout;
9638 VkPipelineLayout pipeline_layout;
9639 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9640 ASSERT_VK_SUCCESS(err);
9642 VkViewport vp = {}; // Just need dummy vp to point to
9644 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9645 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9646 vp_state_ci.scissorCount = 0;
9647 vp_state_ci.viewportCount = 1; // Count mismatch should cause error
9648 vp_state_ci.pViewports = &vp;
9650 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9651 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9652 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9653 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9654 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9655 rs_state_ci.depthClampEnable = VK_FALSE;
9656 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9657 rs_state_ci.depthBiasEnable = VK_FALSE;
9659 VkPipelineShaderStageCreateInfo shaderStages[2];
9660 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9662 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9663 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9664 // but add it to be able to run on more devices
9665 shaderStages[0] = vs.GetStageCreateInfo();
9666 shaderStages[1] = fs.GetStageCreateInfo();
9668 VkGraphicsPipelineCreateInfo gp_ci = {};
9669 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9670 gp_ci.stageCount = 2;
9671 gp_ci.pStages = shaderStages;
9672 gp_ci.pViewportState = &vp_state_ci;
9673 gp_ci.pRasterizationState = &rs_state_ci;
9674 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9675 gp_ci.layout = pipeline_layout;
9676 gp_ci.renderPass = renderPass();
9678 VkPipelineCacheCreateInfo pc_ci = {};
9679 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9681 VkPipeline pipeline;
9682 VkPipelineCache pipelineCache;
9684 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9685 ASSERT_VK_SUCCESS(err);
9686 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9688 m_errorMonitor->VerifyFound();
9690 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9691 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9692 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9693 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9695 // Don't set viewport state in PSO. This is an error b/c we always need this
9697 // for the counts even if the data is going to be set dynamically.
9698 TEST_F(VkLayerTest, PSOViewportStateNotSet) {
9699 // Attempt to Create Gfx Pipeline w/o a VS
9702 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if ");
9704 ASSERT_NO_FATAL_FAILURE(InitState());
9705 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9707 VkDescriptorPoolSize ds_type_count = {};
9708 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9709 ds_type_count.descriptorCount = 1;
9711 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9712 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9713 ds_pool_ci.maxSets = 1;
9714 ds_pool_ci.poolSizeCount = 1;
9715 ds_pool_ci.pPoolSizes = &ds_type_count;
9717 VkDescriptorPool ds_pool;
9718 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9719 ASSERT_VK_SUCCESS(err);
9721 VkDescriptorSetLayoutBinding dsl_binding = {};
9722 dsl_binding.binding = 0;
9723 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9724 dsl_binding.descriptorCount = 1;
9725 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9727 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9728 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9729 ds_layout_ci.bindingCount = 1;
9730 ds_layout_ci.pBindings = &dsl_binding;
9732 VkDescriptorSetLayout ds_layout;
9733 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9734 ASSERT_VK_SUCCESS(err);
9736 VkDescriptorSet descriptorSet;
9737 VkDescriptorSetAllocateInfo alloc_info = {};
9738 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9739 alloc_info.descriptorSetCount = 1;
9740 alloc_info.descriptorPool = ds_pool;
9741 alloc_info.pSetLayouts = &ds_layout;
9742 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9743 ASSERT_VK_SUCCESS(err);
9745 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9746 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9747 pipeline_layout_ci.setLayoutCount = 1;
9748 pipeline_layout_ci.pSetLayouts = &ds_layout;
9750 VkPipelineLayout pipeline_layout;
9751 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9752 ASSERT_VK_SUCCESS(err);
9754 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9755 // Set scissor as dynamic to avoid second error
9756 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9757 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9758 dyn_state_ci.dynamicStateCount = 1;
9759 dyn_state_ci.pDynamicStates = &sc_state;
9761 VkPipelineShaderStageCreateInfo shaderStages[2];
9762 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9764 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9765 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9766 // but add it to be able to run on more devices
9767 shaderStages[0] = vs.GetStageCreateInfo();
9768 shaderStages[1] = fs.GetStageCreateInfo();
9770 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9771 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9772 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9773 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9774 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9775 rs_state_ci.depthClampEnable = VK_FALSE;
9776 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9777 rs_state_ci.depthBiasEnable = VK_FALSE;
9779 VkGraphicsPipelineCreateInfo gp_ci = {};
9780 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9781 gp_ci.stageCount = 2;
9782 gp_ci.pStages = shaderStages;
9783 gp_ci.pRasterizationState = &rs_state_ci;
9784 gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state
9785 // should cause validation error
9786 gp_ci.pDynamicState = &dyn_state_ci;
9787 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9788 gp_ci.layout = pipeline_layout;
9789 gp_ci.renderPass = renderPass();
9791 VkPipelineCacheCreateInfo pc_ci = {};
9792 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9794 VkPipeline pipeline;
9795 VkPipelineCache pipelineCache;
9797 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9798 ASSERT_VK_SUCCESS(err);
9799 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9801 m_errorMonitor->VerifyFound();
9803 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9804 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9805 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9806 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9808 // Create PSO w/o non-zero viewportCount but no viewport data
9809 // Then run second test where dynamic scissor count doesn't match PSO scissor
9811 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) {
9814 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9815 "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
9817 ASSERT_NO_FATAL_FAILURE(InitState());
9819 if (!m_device->phy().features().multiViewport) {
9820 printf("Device does not support multiple viewports/scissors; skipped.\n");
9824 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9826 VkDescriptorPoolSize ds_type_count = {};
9827 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9828 ds_type_count.descriptorCount = 1;
9830 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9831 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9832 ds_pool_ci.maxSets = 1;
9833 ds_pool_ci.poolSizeCount = 1;
9834 ds_pool_ci.pPoolSizes = &ds_type_count;
9836 VkDescriptorPool ds_pool;
9837 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9838 ASSERT_VK_SUCCESS(err);
9840 VkDescriptorSetLayoutBinding dsl_binding = {};
9841 dsl_binding.binding = 0;
9842 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9843 dsl_binding.descriptorCount = 1;
9844 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9846 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9847 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9848 ds_layout_ci.bindingCount = 1;
9849 ds_layout_ci.pBindings = &dsl_binding;
9851 VkDescriptorSetLayout ds_layout;
9852 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9853 ASSERT_VK_SUCCESS(err);
9855 VkDescriptorSet descriptorSet;
9856 VkDescriptorSetAllocateInfo alloc_info = {};
9857 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9858 alloc_info.descriptorSetCount = 1;
9859 alloc_info.descriptorPool = ds_pool;
9860 alloc_info.pSetLayouts = &ds_layout;
9861 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9862 ASSERT_VK_SUCCESS(err);
9864 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9865 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9866 pipeline_layout_ci.setLayoutCount = 1;
9867 pipeline_layout_ci.pSetLayouts = &ds_layout;
9869 VkPipelineLayout pipeline_layout;
9870 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9871 ASSERT_VK_SUCCESS(err);
9873 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9874 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9875 vp_state_ci.viewportCount = 1;
9876 vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error
9877 vp_state_ci.scissorCount = 1;
9878 vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error
9880 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9881 // Set scissor as dynamic to avoid that error
9882 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9883 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9884 dyn_state_ci.dynamicStateCount = 1;
9885 dyn_state_ci.pDynamicStates = &sc_state;
9887 VkPipelineShaderStageCreateInfo shaderStages[2];
9888 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9890 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9891 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9892 // but add it to be able to run on more devices
9893 shaderStages[0] = vs.GetStageCreateInfo();
9894 shaderStages[1] = fs.GetStageCreateInfo();
9896 VkPipelineVertexInputStateCreateInfo vi_ci = {};
9897 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
9898 vi_ci.pNext = nullptr;
9899 vi_ci.vertexBindingDescriptionCount = 0;
9900 vi_ci.pVertexBindingDescriptions = nullptr;
9901 vi_ci.vertexAttributeDescriptionCount = 0;
9902 vi_ci.pVertexAttributeDescriptions = nullptr;
9904 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
9905 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9906 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9908 VkPipelineRasterizationStateCreateInfo rs_ci = {};
9909 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9910 rs_ci.pNext = nullptr;
9912 VkPipelineColorBlendAttachmentState att = {};
9913 att.blendEnable = VK_FALSE;
9914 att.colorWriteMask = 0xf;
9916 VkPipelineColorBlendStateCreateInfo cb_ci = {};
9917 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
9918 cb_ci.pNext = nullptr;
9919 cb_ci.attachmentCount = 1;
9920 cb_ci.pAttachments = &att;
9922 VkGraphicsPipelineCreateInfo gp_ci = {};
9923 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9924 gp_ci.stageCount = 2;
9925 gp_ci.pStages = shaderStages;
9926 gp_ci.pVertexInputState = &vi_ci;
9927 gp_ci.pInputAssemblyState = &ia_ci;
9928 gp_ci.pViewportState = &vp_state_ci;
9929 gp_ci.pRasterizationState = &rs_ci;
9930 gp_ci.pColorBlendState = &cb_ci;
9931 gp_ci.pDynamicState = &dyn_state_ci;
9932 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9933 gp_ci.layout = pipeline_layout;
9934 gp_ci.renderPass = renderPass();
9936 VkPipelineCacheCreateInfo pc_ci = {};
9937 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9939 VkPipeline pipeline;
9940 VkPipelineCache pipelineCache;
9942 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9943 ASSERT_VK_SUCCESS(err);
9944 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9946 m_errorMonitor->VerifyFound();
9948 // Now hit second fail case where we set scissor w/ different count than PSO
9949 // First need to successfully create the PSO from above by setting
9951 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
9953 VkViewport vp = {}; // Just need dummy vp to point to
9954 vp_state_ci.pViewports = &vp;
9955 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9956 ASSERT_VK_SUCCESS(err);
9957 BeginCommandBuffer();
9958 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
9959 VkRect2D scissors[1] = {}; // don't care about data
9960 // Count of 2 doesn't match PSO count of 1
9961 vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
9964 m_errorMonitor->VerifyFound();
9966 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9967 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9968 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9969 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9970 vkDestroyPipeline(m_device->device(), pipeline, NULL);
9972 // Create PSO w/o non-zero scissorCount but no scissor data
9973 // Then run second test where dynamic viewportCount doesn't match PSO
9975 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) {
9978 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
9980 ASSERT_NO_FATAL_FAILURE(InitState());
9982 if (!m_device->phy().features().multiViewport) {
9983 printf("Device does not support multiple viewports/scissors; skipped.\n");
9987 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9989 VkDescriptorPoolSize ds_type_count = {};
9990 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9991 ds_type_count.descriptorCount = 1;
9993 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9994 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9995 ds_pool_ci.maxSets = 1;
9996 ds_pool_ci.poolSizeCount = 1;
9997 ds_pool_ci.pPoolSizes = &ds_type_count;
9999 VkDescriptorPool ds_pool;
10000 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10001 ASSERT_VK_SUCCESS(err);
10003 VkDescriptorSetLayoutBinding dsl_binding = {};
10004 dsl_binding.binding = 0;
10005 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10006 dsl_binding.descriptorCount = 1;
10007 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10009 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10010 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10011 ds_layout_ci.bindingCount = 1;
10012 ds_layout_ci.pBindings = &dsl_binding;
10014 VkDescriptorSetLayout ds_layout;
10015 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10016 ASSERT_VK_SUCCESS(err);
10018 VkDescriptorSet descriptorSet;
10019 VkDescriptorSetAllocateInfo alloc_info = {};
10020 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10021 alloc_info.descriptorSetCount = 1;
10022 alloc_info.descriptorPool = ds_pool;
10023 alloc_info.pSetLayouts = &ds_layout;
10024 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10025 ASSERT_VK_SUCCESS(err);
10027 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10028 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10029 pipeline_layout_ci.setLayoutCount = 1;
10030 pipeline_layout_ci.pSetLayouts = &ds_layout;
10032 VkPipelineLayout pipeline_layout;
10033 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10034 ASSERT_VK_SUCCESS(err);
10036 VkPipelineViewportStateCreateInfo vp_state_ci = {};
10037 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10038 vp_state_ci.scissorCount = 1;
10039 vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error
10040 vp_state_ci.viewportCount = 1;
10041 vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error
10043 VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT;
10044 // Set scissor as dynamic to avoid that error
10045 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10046 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10047 dyn_state_ci.dynamicStateCount = 1;
10048 dyn_state_ci.pDynamicStates = &vp_state;
10050 VkPipelineShaderStageCreateInfo shaderStages[2];
10051 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10053 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10054 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
10055 // but add it to be able to run on more devices
10056 shaderStages[0] = vs.GetStageCreateInfo();
10057 shaderStages[1] = fs.GetStageCreateInfo();
10059 VkPipelineVertexInputStateCreateInfo vi_ci = {};
10060 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10061 vi_ci.pNext = nullptr;
10062 vi_ci.vertexBindingDescriptionCount = 0;
10063 vi_ci.pVertexBindingDescriptions = nullptr;
10064 vi_ci.vertexAttributeDescriptionCount = 0;
10065 vi_ci.pVertexAttributeDescriptions = nullptr;
10067 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10068 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10069 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10071 VkPipelineRasterizationStateCreateInfo rs_ci = {};
10072 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10073 rs_ci.pNext = nullptr;
10075 VkPipelineColorBlendAttachmentState att = {};
10076 att.blendEnable = VK_FALSE;
10077 att.colorWriteMask = 0xf;
10079 VkPipelineColorBlendStateCreateInfo cb_ci = {};
10080 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10081 cb_ci.pNext = nullptr;
10082 cb_ci.attachmentCount = 1;
10083 cb_ci.pAttachments = &att;
10085 VkGraphicsPipelineCreateInfo gp_ci = {};
10086 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10087 gp_ci.stageCount = 2;
10088 gp_ci.pStages = shaderStages;
10089 gp_ci.pVertexInputState = &vi_ci;
10090 gp_ci.pInputAssemblyState = &ia_ci;
10091 gp_ci.pViewportState = &vp_state_ci;
10092 gp_ci.pRasterizationState = &rs_ci;
10093 gp_ci.pColorBlendState = &cb_ci;
10094 gp_ci.pDynamicState = &dyn_state_ci;
10095 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10096 gp_ci.layout = pipeline_layout;
10097 gp_ci.renderPass = renderPass();
10099 VkPipelineCacheCreateInfo pc_ci = {};
10100 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10102 VkPipeline pipeline;
10103 VkPipelineCache pipelineCache;
10105 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10106 ASSERT_VK_SUCCESS(err);
10107 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10109 m_errorMonitor->VerifyFound();
10111 // Now hit second fail case where we set scissor w/ different count than PSO
10112 // First need to successfully create the PSO from above by setting
10114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
10116 VkRect2D sc = {}; // Just need dummy vp to point to
10117 vp_state_ci.pScissors = ≻
10118 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10119 ASSERT_VK_SUCCESS(err);
10120 BeginCommandBuffer();
10121 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10122 VkViewport viewports[1] = {}; // don't care about data
10123 // Count of 2 doesn't match PSO count of 1
10124 vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
10127 m_errorMonitor->VerifyFound();
10129 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10130 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10131 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10132 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10133 vkDestroyPipeline(m_device->device(), pipeline, NULL);
10136 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
10139 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10141 ASSERT_NO_FATAL_FAILURE(InitState());
10142 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10144 VkDescriptorPoolSize ds_type_count = {};
10145 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10146 ds_type_count.descriptorCount = 1;
10148 VkDescriptorPoolCreateInfo ds_pool_ci = {};
10149 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10150 ds_pool_ci.maxSets = 1;
10151 ds_pool_ci.poolSizeCount = 1;
10152 ds_pool_ci.pPoolSizes = &ds_type_count;
10154 VkDescriptorPool ds_pool;
10155 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10156 ASSERT_VK_SUCCESS(err);
10158 VkDescriptorSetLayoutBinding dsl_binding = {};
10159 dsl_binding.binding = 0;
10160 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10161 dsl_binding.descriptorCount = 1;
10162 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10164 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10165 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10166 ds_layout_ci.bindingCount = 1;
10167 ds_layout_ci.pBindings = &dsl_binding;
10169 VkDescriptorSetLayout ds_layout;
10170 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10171 ASSERT_VK_SUCCESS(err);
10173 VkDescriptorSet descriptorSet;
10174 VkDescriptorSetAllocateInfo alloc_info = {};
10175 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10176 alloc_info.descriptorSetCount = 1;
10177 alloc_info.descriptorPool = ds_pool;
10178 alloc_info.pSetLayouts = &ds_layout;
10179 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10180 ASSERT_VK_SUCCESS(err);
10182 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10183 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10184 pipeline_layout_ci.setLayoutCount = 1;
10185 pipeline_layout_ci.pSetLayouts = &ds_layout;
10187 VkPipelineLayout pipeline_layout;
10188 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10189 ASSERT_VK_SUCCESS(err);
10191 VkPipelineViewportStateCreateInfo vp_state_ci = {};
10192 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10193 vp_state_ci.scissorCount = 1;
10194 vp_state_ci.pScissors = NULL;
10195 vp_state_ci.viewportCount = 1;
10196 vp_state_ci.pViewports = NULL;
10198 VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
10199 // Set scissor as dynamic to avoid that error
10200 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10201 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10202 dyn_state_ci.dynamicStateCount = 2;
10203 dyn_state_ci.pDynamicStates = dynamic_states;
10205 VkPipelineShaderStageCreateInfo shaderStages[2];
10206 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10208 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10209 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
10210 this); // TODO - We shouldn't need a fragment shader
10211 // but add it to be able to run on more devices
10212 shaderStages[0] = vs.GetStageCreateInfo();
10213 shaderStages[1] = fs.GetStageCreateInfo();
10215 VkPipelineVertexInputStateCreateInfo vi_ci = {};
10216 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10217 vi_ci.pNext = nullptr;
10218 vi_ci.vertexBindingDescriptionCount = 0;
10219 vi_ci.pVertexBindingDescriptions = nullptr;
10220 vi_ci.vertexAttributeDescriptionCount = 0;
10221 vi_ci.pVertexAttributeDescriptions = nullptr;
10223 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10224 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10225 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10227 VkPipelineRasterizationStateCreateInfo rs_ci = {};
10228 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10229 rs_ci.pNext = nullptr;
10231 // Check too low (line width of -1.0f).
10232 rs_ci.lineWidth = -1.0f;
10234 VkPipelineColorBlendAttachmentState att = {};
10235 att.blendEnable = VK_FALSE;
10236 att.colorWriteMask = 0xf;
10238 VkPipelineColorBlendStateCreateInfo cb_ci = {};
10239 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10240 cb_ci.pNext = nullptr;
10241 cb_ci.attachmentCount = 1;
10242 cb_ci.pAttachments = &att;
10244 VkGraphicsPipelineCreateInfo gp_ci = {};
10245 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10246 gp_ci.stageCount = 2;
10247 gp_ci.pStages = shaderStages;
10248 gp_ci.pVertexInputState = &vi_ci;
10249 gp_ci.pInputAssemblyState = &ia_ci;
10250 gp_ci.pViewportState = &vp_state_ci;
10251 gp_ci.pRasterizationState = &rs_ci;
10252 gp_ci.pColorBlendState = &cb_ci;
10253 gp_ci.pDynamicState = &dyn_state_ci;
10254 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10255 gp_ci.layout = pipeline_layout;
10256 gp_ci.renderPass = renderPass();
10258 VkPipelineCacheCreateInfo pc_ci = {};
10259 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10261 VkPipeline pipeline;
10262 VkPipelineCache pipelineCache;
10264 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10265 ASSERT_VK_SUCCESS(err);
10266 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10268 m_errorMonitor->VerifyFound();
10269 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10271 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10273 // Check too high (line width of 65536.0f).
10274 rs_ci.lineWidth = 65536.0f;
10276 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10277 ASSERT_VK_SUCCESS(err);
10278 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10280 m_errorMonitor->VerifyFound();
10281 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10283 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10285 dyn_state_ci.dynamicStateCount = 3;
10287 rs_ci.lineWidth = 1.0f;
10289 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10290 ASSERT_VK_SUCCESS(err);
10291 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10292 BeginCommandBuffer();
10293 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10295 // Check too low with dynamic setting.
10296 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f);
10297 m_errorMonitor->VerifyFound();
10299 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10301 // Check too high with dynamic setting.
10302 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f);
10303 m_errorMonitor->VerifyFound();
10304 EndCommandBuffer();
10306 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10307 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10308 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10309 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10310 vkDestroyPipeline(m_device->device(), pipeline, NULL);
10313 TEST_F(VkLayerTest, NullRenderPass) {
10314 // Bind a NULL RenderPass
10315 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10316 "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
10318 ASSERT_NO_FATAL_FAILURE(InitState());
10319 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10321 BeginCommandBuffer();
10322 // Don't care about RenderPass handle b/c error should be flagged before
10324 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
10326 m_errorMonitor->VerifyFound();
10329 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
10330 // Bind a BeginRenderPass within an active RenderPass
10331 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10332 "It is invalid to issue this call inside an active render pass");
10334 ASSERT_NO_FATAL_FAILURE(InitState());
10335 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10337 BeginCommandBuffer();
10338 // Just create a dummy Renderpass that's non-NULL so we can get to the
10340 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10342 m_errorMonitor->VerifyFound();
10345 TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
10346 m_errorMonitor->ExpectSuccess();
10348 ASSERT_NO_FATAL_FAILURE(InitState());
10349 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10351 BeginCommandBuffer(); // framework implicitly begins the renderpass.
10352 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
10354 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
10355 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10356 m_errorMonitor->VerifyNotFound();
10357 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10358 m_errorMonitor->VerifyNotFound();
10359 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10360 m_errorMonitor->VerifyNotFound();
10362 m_commandBuffer->EndCommandBuffer();
10363 m_errorMonitor->VerifyNotFound();
10366 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
10367 TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
10368 "the number of renderPass attachments that use loadOp"
10369 "VK_ATTACHMENT_LOAD_OP_CLEAR.");
10371 ASSERT_NO_FATAL_FAILURE(InitState());
10372 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10374 // Create a renderPass with a single attachment that uses loadOp CLEAR
10375 VkAttachmentReference attach = {};
10376 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
10377 VkSubpassDescription subpass = {};
10378 subpass.inputAttachmentCount = 1;
10379 subpass.pInputAttachments = &attach;
10380 VkRenderPassCreateInfo rpci = {};
10381 rpci.subpassCount = 1;
10382 rpci.pSubpasses = &subpass;
10383 rpci.attachmentCount = 1;
10384 VkAttachmentDescription attach_desc = {};
10385 attach_desc.format = VK_FORMAT_UNDEFINED;
10386 // Set loadOp to CLEAR
10387 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10388 rpci.pAttachments = &attach_desc;
10389 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10391 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
10393 VkCommandBufferInheritanceInfo hinfo = {};
10394 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10395 hinfo.renderPass = VK_NULL_HANDLE;
10397 hinfo.framebuffer = VK_NULL_HANDLE;
10398 hinfo.occlusionQueryEnable = VK_FALSE;
10399 hinfo.queryFlags = 0;
10400 hinfo.pipelineStatistics = 0;
10401 VkCommandBufferBeginInfo info = {};
10402 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
10403 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10404 info.pInheritanceInfo = &hinfo;
10406 vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
10407 VkRenderPassBeginInfo rp_begin = {};
10408 rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
10409 rp_begin.pNext = NULL;
10410 rp_begin.renderPass = renderPass();
10411 rp_begin.framebuffer = framebuffer();
10412 rp_begin.clearValueCount = 0; // Should be 1
10414 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but "
10415 "there must be at least 1 entries in "
10416 "pClearValues array to account for ");
10418 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
10420 m_errorMonitor->VerifyFound();
10422 vkDestroyRenderPass(m_device->device(), rp, NULL);
10425 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
10427 TEST_DESCRIPTION("End a command buffer with an active render pass");
10429 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10430 "It is invalid to issue this call inside an active render pass");
10432 ASSERT_NO_FATAL_FAILURE(InitState());
10433 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10435 // The framework's BeginCommandBuffer calls CreateRenderPass
10436 BeginCommandBuffer();
10438 // Call directly into vkEndCommandBuffer instead of the
10439 // the framework's EndCommandBuffer, which inserts a
10441 vkEndCommandBuffer(m_commandBuffer->GetBufferHandle());
10443 m_errorMonitor->VerifyFound();
10445 // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
10446 // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
10449 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
10450 // Call CmdFillBuffer within an active renderpass
10451 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10452 "It is invalid to issue this call inside an active render pass");
10454 ASSERT_NO_FATAL_FAILURE(InitState());
10455 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10457 // Renderpass is started here
10458 BeginCommandBuffer();
10460 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10461 vk_testing::Buffer dstBuffer;
10462 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10464 m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
10466 m_errorMonitor->VerifyFound();
10469 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
10470 // Call CmdUpdateBuffer within an active renderpass
10471 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10472 "It is invalid to issue this call inside an active render pass");
10474 ASSERT_NO_FATAL_FAILURE(InitState());
10475 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10477 // Renderpass is started here
10478 BeginCommandBuffer();
10480 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10481 vk_testing::Buffer dstBuffer;
10482 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10484 VkDeviceSize dstOffset = 0;
10485 VkDeviceSize dataSize = 1024;
10486 const void *pData = NULL;
10488 vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData);
10490 m_errorMonitor->VerifyFound();
10493 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
10494 // Call CmdClearColorImage within an active RenderPass
10495 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10496 "It is invalid to issue this call inside an active render pass");
10498 ASSERT_NO_FATAL_FAILURE(InitState());
10499 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10501 // Renderpass is started here
10502 BeginCommandBuffer();
10504 VkClearColorValue clear_color;
10505 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
10506 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10507 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10508 const int32_t tex_width = 32;
10509 const int32_t tex_height = 32;
10510 VkImageCreateInfo image_create_info = {};
10511 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10512 image_create_info.pNext = NULL;
10513 image_create_info.imageType = VK_IMAGE_TYPE_2D;
10514 image_create_info.format = tex_format;
10515 image_create_info.extent.width = tex_width;
10516 image_create_info.extent.height = tex_height;
10517 image_create_info.extent.depth = 1;
10518 image_create_info.mipLevels = 1;
10519 image_create_info.arrayLayers = 1;
10520 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10521 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
10522 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10524 vk_testing::Image dstImage;
10525 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10527 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
10529 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
10531 m_errorMonitor->VerifyFound();
10534 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) {
10535 // Call CmdClearDepthStencilImage within an active RenderPass
10536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10537 "It is invalid to issue this call inside an active render pass");
10539 ASSERT_NO_FATAL_FAILURE(InitState());
10540 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10542 // Renderpass is started here
10543 BeginCommandBuffer();
10545 VkClearDepthStencilValue clear_value = {0};
10546 VkMemoryPropertyFlags reqs = 0;
10547 VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
10548 image_create_info.imageType = VK_IMAGE_TYPE_2D;
10549 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
10550 image_create_info.extent.width = 64;
10551 image_create_info.extent.height = 64;
10552 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10553 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
10555 vk_testing::Image dstImage;
10556 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10558 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
10560 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(),
10561 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range);
10563 m_errorMonitor->VerifyFound();
10566 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
10567 // Call CmdClearAttachmentss outside of an active RenderPass
10570 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call "
10571 "must be issued inside an active "
10574 ASSERT_NO_FATAL_FAILURE(InitState());
10575 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10577 // Start no RenderPass
10578 err = m_commandBuffer->BeginCommandBuffer();
10579 ASSERT_VK_SUCCESS(err);
10581 VkClearAttachment color_attachment;
10582 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10583 color_attachment.clearValue.color.float32[0] = 0;
10584 color_attachment.clearValue.color.float32[1] = 0;
10585 color_attachment.clearValue.color.float32[2] = 0;
10586 color_attachment.clearValue.color.float32[3] = 0;
10587 color_attachment.colorAttachment = 0;
10588 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
10589 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
10591 m_errorMonitor->VerifyFound();
10594 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
10595 TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is "
10596 "called too many times in a renderpass instance");
10598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance "
10599 "beyond final subpass");
10601 ASSERT_NO_FATAL_FAILURE(InitState());
10602 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10604 BeginCommandBuffer();
10607 vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE);
10608 m_errorMonitor->VerifyFound();
10610 EndCommandBuffer();
10613 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
10614 TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is "
10615 "called before the final subpass has been reached");
10617 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching "
10620 ASSERT_NO_FATAL_FAILURE(InitState());
10621 VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
10622 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
10624 VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
10627 VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
10628 ASSERT_VK_SUCCESS(err);
10630 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
10633 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
10634 ASSERT_VK_SUCCESS(err);
10636 m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin
10638 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
10640 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
10643 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10644 m_errorMonitor->VerifyFound();
10647 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
10648 vkDestroyRenderPass(m_device->device(), rp, nullptr);
10651 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
10652 // Try to add a buffer memory barrier with no buffer.
10653 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10654 "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
10656 ASSERT_NO_FATAL_FAILURE(InitState());
10657 BeginCommandBuffer();
10659 VkBufferMemoryBarrier buf_barrier = {};
10660 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10661 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10662 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10663 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10664 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10665 buf_barrier.buffer = VK_NULL_HANDLE;
10666 buf_barrier.offset = 0;
10667 buf_barrier.size = VK_WHOLE_SIZE;
10668 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10669 nullptr, 1, &buf_barrier, 0, nullptr);
10671 m_errorMonitor->VerifyFound();
10674 TEST_F(VkLayerTest, InvalidBarriers) {
10675 TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
10677 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass");
10679 ASSERT_NO_FATAL_FAILURE(InitState());
10680 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10682 VkMemoryBarrier mem_barrier = {};
10683 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
10684 mem_barrier.pNext = NULL;
10685 mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10686 mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10687 BeginCommandBuffer();
10688 // BeginCommandBuffer() starts a render pass
10689 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
10690 &mem_barrier, 0, nullptr, 0, nullptr);
10691 m_errorMonitor->VerifyFound();
10693 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
10694 VkImageObj image(m_device);
10695 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10696 ASSERT_TRUE(image.initialized());
10697 VkImageMemoryBarrier img_barrier = {};
10698 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10699 img_barrier.pNext = NULL;
10700 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10701 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10702 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10703 // New layout can't be UNDEFINED
10704 img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10705 img_barrier.image = image.handle();
10706 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10707 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10708 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10709 img_barrier.subresourceRange.baseArrayLayer = 0;
10710 img_barrier.subresourceRange.baseMipLevel = 0;
10711 img_barrier.subresourceRange.layerCount = 1;
10712 img_barrier.subresourceRange.levelCount = 1;
10713 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10714 nullptr, 0, nullptr, 1, &img_barrier);
10715 m_errorMonitor->VerifyFound();
10716 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10718 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the "
10720 // baseArrayLayer + layerCount must be <= image's arrayLayers
10721 img_barrier.subresourceRange.baseArrayLayer = 1;
10722 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10723 nullptr, 0, nullptr, 1, &img_barrier);
10724 m_errorMonitor->VerifyFound();
10725 img_barrier.subresourceRange.baseArrayLayer = 0;
10727 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel");
10728 // baseMipLevel + levelCount must be <= image's mipLevels
10729 img_barrier.subresourceRange.baseMipLevel = 1;
10730 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10731 nullptr, 0, nullptr, 1, &img_barrier);
10732 m_errorMonitor->VerifyFound();
10733 img_barrier.subresourceRange.baseMipLevel = 0;
10735 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
10736 vk_testing::Buffer buffer;
10737 buffer.init(*m_device, 256);
10738 VkBufferMemoryBarrier buf_barrier = {};
10739 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10740 buf_barrier.pNext = NULL;
10741 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10742 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10743 buf_barrier.buffer = buffer.handle();
10744 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10745 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10746 buf_barrier.offset = 0;
10747 buf_barrier.size = VK_WHOLE_SIZE;
10748 // Can't send buffer barrier during a render pass
10749 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10750 nullptr, 1, &buf_barrier, 0, nullptr);
10751 m_errorMonitor->VerifyFound();
10752 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10754 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
10755 buf_barrier.offset = 257;
10756 // Offset greater than total size
10757 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10758 nullptr, 1, &buf_barrier, 0, nullptr);
10759 m_errorMonitor->VerifyFound();
10760 buf_barrier.offset = 0;
10762 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
10763 buf_barrier.size = 257;
10764 // Size greater than total size
10765 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10766 nullptr, 1, &buf_barrier, 0, nullptr);
10767 m_errorMonitor->VerifyFound();
10769 // Now exercise barrier aspect bit errors, first DS
10770 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must "
10771 "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
10772 "VK_IMAGE_ASPECT_STENCIL_BIT set.");
10773 VkDepthStencilObj ds_image(m_device);
10774 ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
10775 ASSERT_TRUE(ds_image.initialized());
10776 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10777 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10778 img_barrier.image = ds_image.handle();
10779 // Use of COLOR aspect on DS image is error
10780 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10781 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10782 nullptr, 0, nullptr, 1, &img_barrier);
10783 m_errorMonitor->VerifyFound();
10784 // Now test depth-only
10785 VkFormatProperties format_props;
10787 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
10788 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10789 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must "
10790 "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
10791 VkDepthStencilObj d_image(m_device);
10792 d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
10793 ASSERT_TRUE(d_image.initialized());
10794 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10795 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10796 img_barrier.image = d_image.handle();
10797 // Use of COLOR aspect on depth image is error
10798 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10799 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10800 0, nullptr, 0, nullptr, 1, &img_barrier);
10801 m_errorMonitor->VerifyFound();
10803 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
10804 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10805 // Now test stencil-only
10806 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must "
10807 "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
10808 VkDepthStencilObj s_image(m_device);
10809 s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
10810 ASSERT_TRUE(s_image.initialized());
10811 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10812 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10813 img_barrier.image = s_image.handle();
10814 // Use of COLOR aspect on depth image is error
10815 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10816 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10817 0, nullptr, 0, nullptr, 1, &img_barrier);
10818 m_errorMonitor->VerifyFound();
10820 // Finally test color
10821 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
10822 "have VK_IMAGE_ASPECT_COLOR_BIT set.");
10823 VkImageObj c_image(m_device);
10824 c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10825 ASSERT_TRUE(c_image.initialized());
10826 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10827 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10828 img_barrier.image = c_image.handle();
10829 // Set aspect to depth (non-color)
10830 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
10831 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10832 nullptr, 0, nullptr, 1, &img_barrier);
10833 m_errorMonitor->VerifyFound();
10836 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
10837 // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
10839 m_errorMonitor->SetDesiredFailureMsg(
10840 VK_DEBUG_REPORT_WARNING_BIT_EXT,
10841 "must have required access bit");
10842 ASSERT_NO_FATAL_FAILURE(InitState());
10843 VkImageObj image(m_device);
10844 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10845 ASSERT_TRUE(image.initialized());
10847 VkImageMemoryBarrier barrier = {};
10848 VkImageSubresourceRange range;
10849 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10850 barrier.srcAccessMask = 0;
10851 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
10852 barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
10853 barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10854 barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10855 barrier.image = image.handle();
10856 range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10857 range.baseMipLevel = 0;
10858 range.levelCount = 1;
10859 range.baseArrayLayer = 0;
10860 range.layerCount = 1;
10861 barrier.subresourceRange = range;
10862 VkCommandBufferObj cmdbuf(m_device, m_commandPool);
10863 cmdbuf.BeginCommandBuffer();
10864 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10866 barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10867 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10868 barrier.srcAccessMask = 0;
10869 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
10870 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10873 m_errorMonitor->VerifyFound();
10876 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
10877 // Bind a BeginRenderPass within an active RenderPass
10880 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
10882 ASSERT_NO_FATAL_FAILURE(InitState());
10883 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10885 VkBufferCreateInfo buffCI = {};
10886 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10887 buffCI.size = 1024;
10888 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10889 buffCI.queueFamilyIndexCount = 1;
10890 buffCI.pQueueFamilyIndices = &qfi;
10893 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10894 ASSERT_VK_SUCCESS(err);
10896 BeginCommandBuffer();
10897 ASSERT_VK_SUCCESS(err);
10898 // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
10899 // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10900 // Should error before calling to driver so don't care about actual data
10901 vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16);
10903 m_errorMonitor->VerifyFound();
10905 vkDestroyBuffer(m_device->device(), ib, NULL);
10908 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
10909 // Create an out-of-range queueFamilyIndex
10910 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10911 "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one "
10912 "of the indices specified when the device was created, via the "
10913 "VkDeviceQueueCreateInfo structure.");
10915 ASSERT_NO_FATAL_FAILURE(InitState());
10916 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10917 VkBufferCreateInfo buffCI = {};
10918 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10919 buffCI.size = 1024;
10920 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10921 buffCI.queueFamilyIndexCount = 1;
10922 // Introduce failure by specifying invalid queue_family_index
10923 uint32_t qfi = 777;
10924 buffCI.pQueueFamilyIndices = &qfi;
10925 buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
10928 vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10930 m_errorMonitor->VerifyFound();
10931 vkDestroyBuffer(m_device->device(), ib, NULL);
10934 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
10935 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
10936 " (should only be secondary)");
10938 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
10940 ASSERT_NO_FATAL_FAILURE(InitState());
10941 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10943 BeginCommandBuffer();
10945 VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
10946 vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
10948 m_errorMonitor->VerifyFound();
10951 TEST_F(VkLayerTest, DSUsageBitsErrors) {
10952 TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
10953 "that do not have correct usage bits sets.");
10956 ASSERT_NO_FATAL_FAILURE(InitState());
10957 VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10958 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10959 ds_type_count[i].type = VkDescriptorType(i);
10960 ds_type_count[i].descriptorCount = 1;
10962 VkDescriptorPoolCreateInfo ds_pool_ci = {};
10963 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10964 ds_pool_ci.pNext = NULL;
10965 ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10966 ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10967 ds_pool_ci.pPoolSizes = ds_type_count;
10969 VkDescriptorPool ds_pool;
10970 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10971 ASSERT_VK_SUCCESS(err);
10973 // Create 10 layouts where each has a single descriptor of different type
10974 VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10975 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10976 dsl_binding[i].binding = 0;
10977 dsl_binding[i].descriptorType = VkDescriptorType(i);
10978 dsl_binding[i].descriptorCount = 1;
10979 dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
10980 dsl_binding[i].pImmutableSamplers = NULL;
10983 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10984 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10985 ds_layout_ci.pNext = NULL;
10986 ds_layout_ci.bindingCount = 1;
10987 VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
10988 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10989 ds_layout_ci.pBindings = dsl_binding + i;
10990 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i);
10991 ASSERT_VK_SUCCESS(err);
10993 VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10994 VkDescriptorSetAllocateInfo alloc_info = {};
10995 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10996 alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10997 alloc_info.descriptorPool = ds_pool;
10998 alloc_info.pSetLayouts = ds_layouts;
10999 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
11000 ASSERT_VK_SUCCESS(err);
11002 // Create a buffer & bufferView to be used for invalid updates
11003 VkBufferCreateInfo buff_ci = {};
11004 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11005 // This usage is not valid for any descriptor type
11006 buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
11007 buff_ci.size = 256;
11008 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11010 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11011 ASSERT_VK_SUCCESS(err);
11013 VkBufferViewCreateInfo buff_view_ci = {};
11014 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11015 buff_view_ci.buffer = buffer;
11016 buff_view_ci.format = VK_FORMAT_R8_UNORM;
11017 buff_view_ci.range = VK_WHOLE_SIZE;
11018 VkBufferView buff_view;
11019 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11020 ASSERT_VK_SUCCESS(err);
11022 // Create an image to be used for invalid updates
11023 VkImageCreateInfo image_ci = {};
11024 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11025 image_ci.imageType = VK_IMAGE_TYPE_2D;
11026 image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11027 image_ci.extent.width = 64;
11028 image_ci.extent.height = 64;
11029 image_ci.extent.depth = 1;
11030 image_ci.mipLevels = 1;
11031 image_ci.arrayLayers = 1;
11032 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11033 image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11034 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11035 // This usage is not valid for any descriptor type
11036 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11037 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11039 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11040 ASSERT_VK_SUCCESS(err);
11041 // Bind memory to image
11042 VkMemoryRequirements mem_reqs;
11043 VkDeviceMemory image_mem;
11045 VkMemoryAllocateInfo mem_alloc = {};
11046 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11047 mem_alloc.pNext = NULL;
11048 mem_alloc.allocationSize = 0;
11049 mem_alloc.memoryTypeIndex = 0;
11050 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11051 mem_alloc.allocationSize = mem_reqs.size;
11052 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11054 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11055 ASSERT_VK_SUCCESS(err);
11056 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11057 ASSERT_VK_SUCCESS(err);
11058 // Now create view for image
11059 VkImageViewCreateInfo image_view_ci = {};
11060 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11061 image_view_ci.image = image;
11062 image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11063 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11064 image_view_ci.subresourceRange.layerCount = 1;
11065 image_view_ci.subresourceRange.baseArrayLayer = 0;
11066 image_view_ci.subresourceRange.levelCount = 1;
11067 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11068 VkImageView image_view;
11069 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11070 ASSERT_VK_SUCCESS(err);
11072 VkDescriptorBufferInfo buff_info = {};
11073 buff_info.buffer = buffer;
11074 VkDescriptorImageInfo img_info = {};
11075 img_info.imageView = image_view;
11076 VkWriteDescriptorSet descriptor_write = {};
11077 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11078 descriptor_write.dstBinding = 0;
11079 descriptor_write.descriptorCount = 1;
11080 descriptor_write.pTexelBufferView = &buff_view;
11081 descriptor_write.pBufferInfo = &buff_info;
11082 descriptor_write.pImageInfo = &img_info;
11084 // These error messages align with VkDescriptorType struct
11085 const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor
11086 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11087 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11088 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
11089 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
11090 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
11091 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11092 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11093 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11094 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11095 " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
11096 // Start loop at 1 as SAMPLER desc type has no usage bit error
11097 for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
11098 descriptor_write.descriptorType = VkDescriptorType(i);
11099 descriptor_write.dstSet = descriptor_sets[i];
11100 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]);
11102 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11104 m_errorMonitor->VerifyFound();
11105 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
11107 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
11108 vkDestroyImage(m_device->device(), image, NULL);
11109 vkFreeMemory(m_device->device(), image_mem, NULL);
11110 vkDestroyImageView(m_device->device(), image_view, NULL);
11111 vkDestroyBuffer(m_device->device(), buffer, NULL);
11112 vkDestroyBufferView(m_device->device(), buff_view, NULL);
11113 vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
11114 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11117 TEST_F(VkLayerTest, DSBufferInfoErrors) {
11118 TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect "
11119 "parameters in VkDescriptorBufferInfo struct. This includes:\n"
11120 "1. offset value greater than buffer size\n"
11121 "2. range value of 0\n"
11122 "3. range value greater than buffer (size - offset)");
11125 ASSERT_NO_FATAL_FAILURE(InitState());
11126 VkDescriptorPoolSize ds_type_count = {};
11127 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11128 ds_type_count.descriptorCount = 1;
11130 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11131 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11132 ds_pool_ci.pNext = NULL;
11133 ds_pool_ci.maxSets = 1;
11134 ds_pool_ci.poolSizeCount = 1;
11135 ds_pool_ci.pPoolSizes = &ds_type_count;
11137 VkDescriptorPool ds_pool;
11138 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11139 ASSERT_VK_SUCCESS(err);
11141 // Create layout with single uniform buffer descriptor
11142 VkDescriptorSetLayoutBinding dsl_binding = {};
11143 dsl_binding.binding = 0;
11144 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11145 dsl_binding.descriptorCount = 1;
11146 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11147 dsl_binding.pImmutableSamplers = NULL;
11149 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11150 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11151 ds_layout_ci.pNext = NULL;
11152 ds_layout_ci.bindingCount = 1;
11153 ds_layout_ci.pBindings = &dsl_binding;
11154 VkDescriptorSetLayout ds_layout;
11155 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11156 ASSERT_VK_SUCCESS(err);
11158 VkDescriptorSet descriptor_set = {};
11159 VkDescriptorSetAllocateInfo alloc_info = {};
11160 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11161 alloc_info.descriptorSetCount = 1;
11162 alloc_info.descriptorPool = ds_pool;
11163 alloc_info.pSetLayouts = &ds_layout;
11164 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11165 ASSERT_VK_SUCCESS(err);
11167 // Create a buffer to be used for invalid updates
11168 VkBufferCreateInfo buff_ci = {};
11169 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11170 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
11171 buff_ci.size = 256;
11172 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11174 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11175 ASSERT_VK_SUCCESS(err);
11176 // Have to bind memory to buffer before descriptor update
11177 VkMemoryAllocateInfo mem_alloc = {};
11178 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11179 mem_alloc.pNext = NULL;
11180 mem_alloc.allocationSize = 256;
11181 mem_alloc.memoryTypeIndex = 0;
11183 VkMemoryRequirements mem_reqs;
11184 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
11185 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11187 vkDestroyBuffer(m_device->device(), buffer, NULL);
11191 VkDeviceMemory mem;
11192 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
11193 ASSERT_VK_SUCCESS(err);
11194 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
11195 ASSERT_VK_SUCCESS(err);
11197 VkDescriptorBufferInfo buff_info = {};
11198 buff_info.buffer = buffer;
11199 // First make offset 1 larger than buffer size
11200 buff_info.offset = 257;
11201 buff_info.range = VK_WHOLE_SIZE;
11202 VkWriteDescriptorSet descriptor_write = {};
11203 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11204 descriptor_write.dstBinding = 0;
11205 descriptor_write.descriptorCount = 1;
11206 descriptor_write.pTexelBufferView = nullptr;
11207 descriptor_write.pBufferInfo = &buff_info;
11208 descriptor_write.pImageInfo = nullptr;
11210 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11211 descriptor_write.dstSet = descriptor_set;
11212 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer ");
11214 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11216 m_errorMonitor->VerifyFound();
11217 // Now cause error due to range of 0
11218 buff_info.offset = 0;
11219 buff_info.range = 0;
11220 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11221 " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
11223 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11225 m_errorMonitor->VerifyFound();
11226 // Now cause error due to range exceeding buffer size - offset
11227 buff_info.offset = 128;
11228 buff_info.range = 200;
11229 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size ");
11231 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11233 m_errorMonitor->VerifyFound();
11234 vkFreeMemory(m_device->device(), mem, NULL);
11235 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11236 vkDestroyBuffer(m_device->device(), buffer, NULL);
11237 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11238 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11241 TEST_F(VkLayerTest, DSAspectBitsErrors) {
11242 // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
11243 // are set, but could expand this test to hit more cases.
11244 TEST_DESCRIPTION("Attempt to update descriptor sets for images "
11245 "that do not have correct aspect bits sets.");
11248 ASSERT_NO_FATAL_FAILURE(InitState());
11249 VkDescriptorPoolSize ds_type_count = {};
11250 ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11251 ds_type_count.descriptorCount = 1;
11253 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11254 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11255 ds_pool_ci.pNext = NULL;
11256 ds_pool_ci.maxSets = 5;
11257 ds_pool_ci.poolSizeCount = 1;
11258 ds_pool_ci.pPoolSizes = &ds_type_count;
11260 VkDescriptorPool ds_pool;
11261 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11262 ASSERT_VK_SUCCESS(err);
11264 VkDescriptorSetLayoutBinding dsl_binding = {};
11265 dsl_binding.binding = 0;
11266 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11267 dsl_binding.descriptorCount = 1;
11268 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11269 dsl_binding.pImmutableSamplers = NULL;
11271 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11272 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11273 ds_layout_ci.pNext = NULL;
11274 ds_layout_ci.bindingCount = 1;
11275 ds_layout_ci.pBindings = &dsl_binding;
11276 VkDescriptorSetLayout ds_layout;
11277 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11278 ASSERT_VK_SUCCESS(err);
11280 VkDescriptorSet descriptor_set = {};
11281 VkDescriptorSetAllocateInfo alloc_info = {};
11282 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11283 alloc_info.descriptorSetCount = 1;
11284 alloc_info.descriptorPool = ds_pool;
11285 alloc_info.pSetLayouts = &ds_layout;
11286 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11287 ASSERT_VK_SUCCESS(err);
11289 // Create an image to be used for invalid updates
11290 VkImageCreateInfo image_ci = {};
11291 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11292 image_ci.imageType = VK_IMAGE_TYPE_2D;
11293 image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11294 image_ci.extent.width = 64;
11295 image_ci.extent.height = 64;
11296 image_ci.extent.depth = 1;
11297 image_ci.mipLevels = 1;
11298 image_ci.arrayLayers = 1;
11299 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11300 image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11301 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11302 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11303 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11305 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11306 ASSERT_VK_SUCCESS(err);
11307 // Bind memory to image
11308 VkMemoryRequirements mem_reqs;
11309 VkDeviceMemory image_mem;
11311 VkMemoryAllocateInfo mem_alloc = {};
11312 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11313 mem_alloc.pNext = NULL;
11314 mem_alloc.allocationSize = 0;
11315 mem_alloc.memoryTypeIndex = 0;
11316 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11317 mem_alloc.allocationSize = mem_reqs.size;
11318 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11320 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11321 ASSERT_VK_SUCCESS(err);
11322 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11323 ASSERT_VK_SUCCESS(err);
11324 // Now create view for image
11325 VkImageViewCreateInfo image_view_ci = {};
11326 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11327 image_view_ci.image = image;
11328 image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11329 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11330 image_view_ci.subresourceRange.layerCount = 1;
11331 image_view_ci.subresourceRange.baseArrayLayer = 0;
11332 image_view_ci.subresourceRange.levelCount = 1;
11333 // Setting both depth & stencil aspect bits is illegal for descriptor
11334 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
11336 VkImageView image_view;
11337 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11338 ASSERT_VK_SUCCESS(err);
11340 VkDescriptorImageInfo img_info = {};
11341 img_info.imageView = image_view;
11342 VkWriteDescriptorSet descriptor_write = {};
11343 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11344 descriptor_write.dstBinding = 0;
11345 descriptor_write.descriptorCount = 1;
11346 descriptor_write.pTexelBufferView = NULL;
11347 descriptor_write.pBufferInfo = NULL;
11348 descriptor_write.pImageInfo = &img_info;
11349 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11350 descriptor_write.dstSet = descriptor_set;
11351 const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
11352 "or VK_IMAGE_ASPECT_STENCIL_BIT ";
11353 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
11355 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11357 m_errorMonitor->VerifyFound();
11358 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11359 vkDestroyImage(m_device->device(), image, NULL);
11360 vkFreeMemory(m_device->device(), image_mem, NULL);
11361 vkDestroyImageView(m_device->device(), image_view, NULL);
11362 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11363 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11366 TEST_F(VkLayerTest, DSTypeMismatch) {
11367 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
11370 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11371 " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update "
11372 "type is VK_DESCRIPTOR_TYPE_SAMPLER");
11374 ASSERT_NO_FATAL_FAILURE(InitState());
11375 // VkDescriptorSetObj descriptorSet(m_device);
11376 VkDescriptorPoolSize ds_type_count = {};
11377 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11378 ds_type_count.descriptorCount = 1;
11380 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11381 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11382 ds_pool_ci.pNext = NULL;
11383 ds_pool_ci.maxSets = 1;
11384 ds_pool_ci.poolSizeCount = 1;
11385 ds_pool_ci.pPoolSizes = &ds_type_count;
11387 VkDescriptorPool ds_pool;
11388 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11389 ASSERT_VK_SUCCESS(err);
11390 VkDescriptorSetLayoutBinding dsl_binding = {};
11391 dsl_binding.binding = 0;
11392 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11393 dsl_binding.descriptorCount = 1;
11394 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11395 dsl_binding.pImmutableSamplers = NULL;
11397 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11398 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11399 ds_layout_ci.pNext = NULL;
11400 ds_layout_ci.bindingCount = 1;
11401 ds_layout_ci.pBindings = &dsl_binding;
11403 VkDescriptorSetLayout ds_layout;
11404 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11405 ASSERT_VK_SUCCESS(err);
11407 VkDescriptorSet descriptorSet;
11408 VkDescriptorSetAllocateInfo alloc_info = {};
11409 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11410 alloc_info.descriptorSetCount = 1;
11411 alloc_info.descriptorPool = ds_pool;
11412 alloc_info.pSetLayouts = &ds_layout;
11413 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11414 ASSERT_VK_SUCCESS(err);
11416 VkSamplerCreateInfo sampler_ci = {};
11417 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11418 sampler_ci.pNext = NULL;
11419 sampler_ci.magFilter = VK_FILTER_NEAREST;
11420 sampler_ci.minFilter = VK_FILTER_NEAREST;
11421 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11422 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11423 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11424 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11425 sampler_ci.mipLodBias = 1.0;
11426 sampler_ci.anisotropyEnable = VK_FALSE;
11427 sampler_ci.maxAnisotropy = 1;
11428 sampler_ci.compareEnable = VK_FALSE;
11429 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11430 sampler_ci.minLod = 1.0;
11431 sampler_ci.maxLod = 1.0;
11432 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11433 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11435 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11436 ASSERT_VK_SUCCESS(err);
11438 VkDescriptorImageInfo info = {};
11439 info.sampler = sampler;
11441 VkWriteDescriptorSet descriptor_write;
11442 memset(&descriptor_write, 0, sizeof(descriptor_write));
11443 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11444 descriptor_write.dstSet = descriptorSet;
11445 descriptor_write.descriptorCount = 1;
11446 // This is a mismatched type for the layout which expects BUFFER
11447 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11448 descriptor_write.pImageInfo = &info;
11450 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11452 m_errorMonitor->VerifyFound();
11454 vkDestroySampler(m_device->device(), sampler, NULL);
11455 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11456 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11459 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
11460 // For overlapping Update, have arrayIndex exceed that of layout
11463 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11464 " binding #0 with 1 total descriptors but update of 1 descriptors "
11465 "starting at binding offset of 0 combined with update array element "
11466 "offset of 1 oversteps the size of this descriptor set.");
11468 ASSERT_NO_FATAL_FAILURE(InitState());
11469 // VkDescriptorSetObj descriptorSet(m_device);
11470 VkDescriptorPoolSize ds_type_count = {};
11471 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11472 ds_type_count.descriptorCount = 1;
11474 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11475 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11476 ds_pool_ci.pNext = NULL;
11477 ds_pool_ci.maxSets = 1;
11478 ds_pool_ci.poolSizeCount = 1;
11479 ds_pool_ci.pPoolSizes = &ds_type_count;
11481 VkDescriptorPool ds_pool;
11482 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11483 ASSERT_VK_SUCCESS(err);
11485 VkDescriptorSetLayoutBinding dsl_binding = {};
11486 dsl_binding.binding = 0;
11487 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11488 dsl_binding.descriptorCount = 1;
11489 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11490 dsl_binding.pImmutableSamplers = NULL;
11492 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11493 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11494 ds_layout_ci.pNext = NULL;
11495 ds_layout_ci.bindingCount = 1;
11496 ds_layout_ci.pBindings = &dsl_binding;
11498 VkDescriptorSetLayout ds_layout;
11499 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11500 ASSERT_VK_SUCCESS(err);
11502 VkDescriptorSet descriptorSet;
11503 VkDescriptorSetAllocateInfo alloc_info = {};
11504 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11505 alloc_info.descriptorSetCount = 1;
11506 alloc_info.descriptorPool = ds_pool;
11507 alloc_info.pSetLayouts = &ds_layout;
11508 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11509 ASSERT_VK_SUCCESS(err);
11511 // Correctly update descriptor to avoid "NOT_UPDATED" error
11512 VkDescriptorBufferInfo buff_info = {};
11513 buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test
11514 buff_info.offset = 0;
11515 buff_info.range = 1024;
11517 VkWriteDescriptorSet descriptor_write;
11518 memset(&descriptor_write, 0, sizeof(descriptor_write));
11519 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11520 descriptor_write.dstSet = descriptorSet;
11521 descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
11522 descriptor_write.descriptorCount = 1;
11523 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11524 descriptor_write.pBufferInfo = &buff_info;
11526 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11528 m_errorMonitor->VerifyFound();
11530 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11531 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11534 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
11535 // Create layout w/ count of 1 and attempt update to that layout w/ binding
11539 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2.");
11541 ASSERT_NO_FATAL_FAILURE(InitState());
11542 // VkDescriptorSetObj descriptorSet(m_device);
11543 VkDescriptorPoolSize ds_type_count = {};
11544 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11545 ds_type_count.descriptorCount = 1;
11547 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11548 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11549 ds_pool_ci.pNext = NULL;
11550 ds_pool_ci.maxSets = 1;
11551 ds_pool_ci.poolSizeCount = 1;
11552 ds_pool_ci.pPoolSizes = &ds_type_count;
11554 VkDescriptorPool ds_pool;
11555 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11556 ASSERT_VK_SUCCESS(err);
11558 VkDescriptorSetLayoutBinding dsl_binding = {};
11559 dsl_binding.binding = 0;
11560 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11561 dsl_binding.descriptorCount = 1;
11562 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11563 dsl_binding.pImmutableSamplers = NULL;
11565 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11566 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11567 ds_layout_ci.pNext = NULL;
11568 ds_layout_ci.bindingCount = 1;
11569 ds_layout_ci.pBindings = &dsl_binding;
11570 VkDescriptorSetLayout ds_layout;
11571 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11572 ASSERT_VK_SUCCESS(err);
11574 VkDescriptorSet descriptorSet;
11575 VkDescriptorSetAllocateInfo alloc_info = {};
11576 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11577 alloc_info.descriptorSetCount = 1;
11578 alloc_info.descriptorPool = ds_pool;
11579 alloc_info.pSetLayouts = &ds_layout;
11580 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11581 ASSERT_VK_SUCCESS(err);
11583 VkSamplerCreateInfo sampler_ci = {};
11584 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11585 sampler_ci.pNext = NULL;
11586 sampler_ci.magFilter = VK_FILTER_NEAREST;
11587 sampler_ci.minFilter = VK_FILTER_NEAREST;
11588 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11589 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11590 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11591 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11592 sampler_ci.mipLodBias = 1.0;
11593 sampler_ci.anisotropyEnable = VK_FALSE;
11594 sampler_ci.maxAnisotropy = 1;
11595 sampler_ci.compareEnable = VK_FALSE;
11596 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11597 sampler_ci.minLod = 1.0;
11598 sampler_ci.maxLod = 1.0;
11599 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11600 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11603 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11604 ASSERT_VK_SUCCESS(err);
11606 VkDescriptorImageInfo info = {};
11607 info.sampler = sampler;
11609 VkWriteDescriptorSet descriptor_write;
11610 memset(&descriptor_write, 0, sizeof(descriptor_write));
11611 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11612 descriptor_write.dstSet = descriptorSet;
11613 descriptor_write.dstBinding = 2;
11614 descriptor_write.descriptorCount = 1;
11615 // This is the wrong type, but out of bounds will be flagged first
11616 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11617 descriptor_write.pImageInfo = &info;
11619 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11621 m_errorMonitor->VerifyFound();
11623 vkDestroySampler(m_device->device(), sampler, NULL);
11624 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11625 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11628 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
11629 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
11633 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
11635 ASSERT_NO_FATAL_FAILURE(InitState());
11637 VkDescriptorPoolSize ds_type_count = {};
11638 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11639 ds_type_count.descriptorCount = 1;
11641 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11642 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11643 ds_pool_ci.pNext = NULL;
11644 ds_pool_ci.maxSets = 1;
11645 ds_pool_ci.poolSizeCount = 1;
11646 ds_pool_ci.pPoolSizes = &ds_type_count;
11648 VkDescriptorPool ds_pool;
11649 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11650 ASSERT_VK_SUCCESS(err);
11651 VkDescriptorSetLayoutBinding dsl_binding = {};
11652 dsl_binding.binding = 0;
11653 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11654 dsl_binding.descriptorCount = 1;
11655 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11656 dsl_binding.pImmutableSamplers = NULL;
11658 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11659 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11660 ds_layout_ci.pNext = NULL;
11661 ds_layout_ci.bindingCount = 1;
11662 ds_layout_ci.pBindings = &dsl_binding;
11664 VkDescriptorSetLayout ds_layout;
11665 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11666 ASSERT_VK_SUCCESS(err);
11668 VkDescriptorSet descriptorSet;
11669 VkDescriptorSetAllocateInfo alloc_info = {};
11670 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11671 alloc_info.descriptorSetCount = 1;
11672 alloc_info.descriptorPool = ds_pool;
11673 alloc_info.pSetLayouts = &ds_layout;
11674 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11675 ASSERT_VK_SUCCESS(err);
11677 VkSamplerCreateInfo sampler_ci = {};
11678 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11679 sampler_ci.pNext = NULL;
11680 sampler_ci.magFilter = VK_FILTER_NEAREST;
11681 sampler_ci.minFilter = VK_FILTER_NEAREST;
11682 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11683 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11684 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11685 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11686 sampler_ci.mipLodBias = 1.0;
11687 sampler_ci.anisotropyEnable = VK_FALSE;
11688 sampler_ci.maxAnisotropy = 1;
11689 sampler_ci.compareEnable = VK_FALSE;
11690 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11691 sampler_ci.minLod = 1.0;
11692 sampler_ci.maxLod = 1.0;
11693 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11694 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11696 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11697 ASSERT_VK_SUCCESS(err);
11699 VkDescriptorImageInfo info = {};
11700 info.sampler = sampler;
11702 VkWriteDescriptorSet descriptor_write;
11703 memset(&descriptor_write, 0, sizeof(descriptor_write));
11704 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
11705 descriptor_write.dstSet = descriptorSet;
11706 descriptor_write.descriptorCount = 1;
11707 // This is the wrong type, but out of bounds will be flagged first
11708 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11709 descriptor_write.pImageInfo = &info;
11711 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11713 m_errorMonitor->VerifyFound();
11715 vkDestroySampler(m_device->device(), sampler, NULL);
11716 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11717 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11720 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
11721 // Create a single Sampler descriptor and send it an invalid Sampler
11724 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11725 "Attempted write update to sampler descriptor with invalid sampler");
11727 ASSERT_NO_FATAL_FAILURE(InitState());
11728 // TODO : Farm Descriptor setup code to helper function(s) to reduce copied
11730 VkDescriptorPoolSize ds_type_count = {};
11731 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
11732 ds_type_count.descriptorCount = 1;
11734 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11735 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11736 ds_pool_ci.pNext = NULL;
11737 ds_pool_ci.maxSets = 1;
11738 ds_pool_ci.poolSizeCount = 1;
11739 ds_pool_ci.pPoolSizes = &ds_type_count;
11741 VkDescriptorPool ds_pool;
11742 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11743 ASSERT_VK_SUCCESS(err);
11745 VkDescriptorSetLayoutBinding dsl_binding = {};
11746 dsl_binding.binding = 0;
11747 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11748 dsl_binding.descriptorCount = 1;
11749 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11750 dsl_binding.pImmutableSamplers = NULL;
11752 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11753 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11754 ds_layout_ci.pNext = NULL;
11755 ds_layout_ci.bindingCount = 1;
11756 ds_layout_ci.pBindings = &dsl_binding;
11757 VkDescriptorSetLayout ds_layout;
11758 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11759 ASSERT_VK_SUCCESS(err);
11761 VkDescriptorSet descriptorSet;
11762 VkDescriptorSetAllocateInfo alloc_info = {};
11763 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11764 alloc_info.descriptorSetCount = 1;
11765 alloc_info.descriptorPool = ds_pool;
11766 alloc_info.pSetLayouts = &ds_layout;
11767 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11768 ASSERT_VK_SUCCESS(err);
11770 VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle
11772 VkDescriptorImageInfo descriptor_info;
11773 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11774 descriptor_info.sampler = sampler;
11776 VkWriteDescriptorSet descriptor_write;
11777 memset(&descriptor_write, 0, sizeof(descriptor_write));
11778 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11779 descriptor_write.dstSet = descriptorSet;
11780 descriptor_write.dstBinding = 0;
11781 descriptor_write.descriptorCount = 1;
11782 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11783 descriptor_write.pImageInfo = &descriptor_info;
11785 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11787 m_errorMonitor->VerifyFound();
11789 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11790 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11793 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
11794 // Create a single combined Image/Sampler descriptor and send it an invalid
11798 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined "
11799 "image sampler descriptor failed due "
11800 "to: Invalid VkImageView:");
11802 ASSERT_NO_FATAL_FAILURE(InitState());
11803 VkDescriptorPoolSize ds_type_count = {};
11804 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11805 ds_type_count.descriptorCount = 1;
11807 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11808 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11809 ds_pool_ci.pNext = NULL;
11810 ds_pool_ci.maxSets = 1;
11811 ds_pool_ci.poolSizeCount = 1;
11812 ds_pool_ci.pPoolSizes = &ds_type_count;
11814 VkDescriptorPool ds_pool;
11815 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11816 ASSERT_VK_SUCCESS(err);
11818 VkDescriptorSetLayoutBinding dsl_binding = {};
11819 dsl_binding.binding = 0;
11820 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11821 dsl_binding.descriptorCount = 1;
11822 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11823 dsl_binding.pImmutableSamplers = NULL;
11825 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11826 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11827 ds_layout_ci.pNext = NULL;
11828 ds_layout_ci.bindingCount = 1;
11829 ds_layout_ci.pBindings = &dsl_binding;
11830 VkDescriptorSetLayout ds_layout;
11831 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11832 ASSERT_VK_SUCCESS(err);
11834 VkDescriptorSet descriptorSet;
11835 VkDescriptorSetAllocateInfo alloc_info = {};
11836 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11837 alloc_info.descriptorSetCount = 1;
11838 alloc_info.descriptorPool = ds_pool;
11839 alloc_info.pSetLayouts = &ds_layout;
11840 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11841 ASSERT_VK_SUCCESS(err);
11843 VkSamplerCreateInfo sampler_ci = {};
11844 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11845 sampler_ci.pNext = NULL;
11846 sampler_ci.magFilter = VK_FILTER_NEAREST;
11847 sampler_ci.minFilter = VK_FILTER_NEAREST;
11848 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11849 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11850 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11851 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11852 sampler_ci.mipLodBias = 1.0;
11853 sampler_ci.anisotropyEnable = VK_FALSE;
11854 sampler_ci.maxAnisotropy = 1;
11855 sampler_ci.compareEnable = VK_FALSE;
11856 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11857 sampler_ci.minLod = 1.0;
11858 sampler_ci.maxLod = 1.0;
11859 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11860 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11863 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11864 ASSERT_VK_SUCCESS(err);
11866 VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object
11868 VkDescriptorImageInfo descriptor_info;
11869 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11870 descriptor_info.sampler = sampler;
11871 descriptor_info.imageView = view;
11873 VkWriteDescriptorSet descriptor_write;
11874 memset(&descriptor_write, 0, sizeof(descriptor_write));
11875 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11876 descriptor_write.dstSet = descriptorSet;
11877 descriptor_write.dstBinding = 0;
11878 descriptor_write.descriptorCount = 1;
11879 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11880 descriptor_write.pImageInfo = &descriptor_info;
11882 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11884 m_errorMonitor->VerifyFound();
11886 vkDestroySampler(m_device->device(), sampler, NULL);
11887 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11888 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11891 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
11892 // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
11896 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type "
11897 "VK_DESCRIPTOR_TYPE_SAMPLER. Types do "
11900 ASSERT_NO_FATAL_FAILURE(InitState());
11901 // VkDescriptorSetObj descriptorSet(m_device);
11902 VkDescriptorPoolSize ds_type_count[2] = {};
11903 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11904 ds_type_count[0].descriptorCount = 1;
11905 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
11906 ds_type_count[1].descriptorCount = 1;
11908 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11909 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11910 ds_pool_ci.pNext = NULL;
11911 ds_pool_ci.maxSets = 1;
11912 ds_pool_ci.poolSizeCount = 2;
11913 ds_pool_ci.pPoolSizes = ds_type_count;
11915 VkDescriptorPool ds_pool;
11916 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11917 ASSERT_VK_SUCCESS(err);
11918 VkDescriptorSetLayoutBinding dsl_binding[2] = {};
11919 dsl_binding[0].binding = 0;
11920 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11921 dsl_binding[0].descriptorCount = 1;
11922 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
11923 dsl_binding[0].pImmutableSamplers = NULL;
11924 dsl_binding[1].binding = 1;
11925 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11926 dsl_binding[1].descriptorCount = 1;
11927 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
11928 dsl_binding[1].pImmutableSamplers = NULL;
11930 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11931 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11932 ds_layout_ci.pNext = NULL;
11933 ds_layout_ci.bindingCount = 2;
11934 ds_layout_ci.pBindings = dsl_binding;
11936 VkDescriptorSetLayout ds_layout;
11937 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11938 ASSERT_VK_SUCCESS(err);
11940 VkDescriptorSet descriptorSet;
11941 VkDescriptorSetAllocateInfo alloc_info = {};
11942 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11943 alloc_info.descriptorSetCount = 1;
11944 alloc_info.descriptorPool = ds_pool;
11945 alloc_info.pSetLayouts = &ds_layout;
11946 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11947 ASSERT_VK_SUCCESS(err);
11949 VkSamplerCreateInfo sampler_ci = {};
11950 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11951 sampler_ci.pNext = NULL;
11952 sampler_ci.magFilter = VK_FILTER_NEAREST;
11953 sampler_ci.minFilter = VK_FILTER_NEAREST;
11954 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11955 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11956 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11957 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11958 sampler_ci.mipLodBias = 1.0;
11959 sampler_ci.anisotropyEnable = VK_FALSE;
11960 sampler_ci.maxAnisotropy = 1;
11961 sampler_ci.compareEnable = VK_FALSE;
11962 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11963 sampler_ci.minLod = 1.0;
11964 sampler_ci.maxLod = 1.0;
11965 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11966 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11969 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11970 ASSERT_VK_SUCCESS(err);
11972 VkDescriptorImageInfo info = {};
11973 info.sampler = sampler;
11975 VkWriteDescriptorSet descriptor_write;
11976 memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
11977 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11978 descriptor_write.dstSet = descriptorSet;
11979 descriptor_write.dstBinding = 1; // SAMPLER binding from layout above
11980 descriptor_write.descriptorCount = 1;
11981 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11982 descriptor_write.pImageInfo = &info;
11983 // This write update should succeed
11984 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11985 // Now perform a copy update that fails due to type mismatch
11986 VkCopyDescriptorSet copy_ds_update;
11987 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
11988 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
11989 copy_ds_update.srcSet = descriptorSet;
11990 copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding
11991 copy_ds_update.dstSet = descriptorSet;
11992 copy_ds_update.dstBinding = 0; // ERROR : copy to UNIFORM binding
11993 copy_ds_update.descriptorCount = 1; // copy 1 descriptor
11994 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
11996 m_errorMonitor->VerifyFound();
11997 // Now perform a copy update that fails due to binding out of bounds
11998 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
11999 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
12000 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12001 copy_ds_update.srcSet = descriptorSet;
12002 copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout
12003 copy_ds_update.dstSet = descriptorSet;
12004 copy_ds_update.dstBinding = 0;
12005 copy_ds_update.descriptorCount = 1; // Copy 1 descriptor
12006 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
12008 m_errorMonitor->VerifyFound();
12010 // Now perform a copy update that fails due to binding out of bounds
12011 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus "
12012 "update array offset of 0 and update of "
12013 "5 descriptors oversteps total number "
12014 "of descriptors in set: 2.");
12016 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
12017 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12018 copy_ds_update.srcSet = descriptorSet;
12019 copy_ds_update.srcBinding = 1;
12020 copy_ds_update.dstSet = descriptorSet;
12021 copy_ds_update.dstBinding = 0;
12022 copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout)
12023 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
12025 m_errorMonitor->VerifyFound();
12027 vkDestroySampler(m_device->device(), sampler, NULL);
12028 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12029 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12032 TEST_F(VkLayerTest, NumSamplesMismatch) {
12033 // Create CommandBuffer where MSAA samples doesn't match RenderPass
12037 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
12039 ASSERT_NO_FATAL_FAILURE(InitState());
12040 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12041 VkDescriptorPoolSize ds_type_count = {};
12042 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12043 ds_type_count.descriptorCount = 1;
12045 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12046 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12047 ds_pool_ci.pNext = NULL;
12048 ds_pool_ci.maxSets = 1;
12049 ds_pool_ci.poolSizeCount = 1;
12050 ds_pool_ci.pPoolSizes = &ds_type_count;
12052 VkDescriptorPool ds_pool;
12053 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12054 ASSERT_VK_SUCCESS(err);
12056 VkDescriptorSetLayoutBinding dsl_binding = {};
12057 dsl_binding.binding = 0;
12058 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12059 dsl_binding.descriptorCount = 1;
12060 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12061 dsl_binding.pImmutableSamplers = NULL;
12063 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12064 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12065 ds_layout_ci.pNext = NULL;
12066 ds_layout_ci.bindingCount = 1;
12067 ds_layout_ci.pBindings = &dsl_binding;
12069 VkDescriptorSetLayout ds_layout;
12070 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12071 ASSERT_VK_SUCCESS(err);
12073 VkDescriptorSet descriptorSet;
12074 VkDescriptorSetAllocateInfo alloc_info = {};
12075 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12076 alloc_info.descriptorSetCount = 1;
12077 alloc_info.descriptorPool = ds_pool;
12078 alloc_info.pSetLayouts = &ds_layout;
12079 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12080 ASSERT_VK_SUCCESS(err);
12082 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12083 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12084 pipe_ms_state_ci.pNext = NULL;
12085 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12086 pipe_ms_state_ci.sampleShadingEnable = 0;
12087 pipe_ms_state_ci.minSampleShading = 1.0;
12088 pipe_ms_state_ci.pSampleMask = NULL;
12090 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12091 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12092 pipeline_layout_ci.pNext = NULL;
12093 pipeline_layout_ci.setLayoutCount = 1;
12094 pipeline_layout_ci.pSetLayouts = &ds_layout;
12096 VkPipelineLayout pipeline_layout;
12097 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12098 ASSERT_VK_SUCCESS(err);
12100 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12101 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12102 // but add it to be able to run on more devices
12103 VkPipelineObj pipe(m_device);
12104 pipe.AddShader(&vs);
12105 pipe.AddShader(&fs);
12106 pipe.AddColorAttachment();
12107 pipe.SetMSAA(&pipe_ms_state_ci);
12108 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12110 BeginCommandBuffer();
12111 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12113 // Render triangle (the error should trigger on the attempt to draw).
12116 // Finalize recording of the command buffer
12117 EndCommandBuffer();
12119 m_errorMonitor->VerifyFound();
12121 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12122 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12123 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12126 TEST_F(VkLayerTest, RenderPassIncompatible) {
12127 TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
12128 "Initial case is drawing with an active renderpass that's "
12129 "not compatible with the bound PSO's creation renderpass");
12132 ASSERT_NO_FATAL_FAILURE(InitState());
12133 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12135 VkDescriptorSetLayoutBinding dsl_binding = {};
12136 dsl_binding.binding = 0;
12137 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12138 dsl_binding.descriptorCount = 1;
12139 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12140 dsl_binding.pImmutableSamplers = NULL;
12142 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12143 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12144 ds_layout_ci.pNext = NULL;
12145 ds_layout_ci.bindingCount = 1;
12146 ds_layout_ci.pBindings = &dsl_binding;
12148 VkDescriptorSetLayout ds_layout;
12149 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12150 ASSERT_VK_SUCCESS(err);
12152 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12153 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12154 pipeline_layout_ci.pNext = NULL;
12155 pipeline_layout_ci.setLayoutCount = 1;
12156 pipeline_layout_ci.pSetLayouts = &ds_layout;
12158 VkPipelineLayout pipeline_layout;
12159 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12160 ASSERT_VK_SUCCESS(err);
12162 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12163 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12164 // but add it to be able to run on more devices
12165 // Create a renderpass that will be incompatible with default renderpass
12166 VkAttachmentReference attach = {};
12167 attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12168 VkAttachmentReference color_att = {};
12169 color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12170 VkSubpassDescription subpass = {};
12171 subpass.inputAttachmentCount = 1;
12172 subpass.pInputAttachments = &attach;
12173 subpass.colorAttachmentCount = 1;
12174 subpass.pColorAttachments = &color_att;
12175 VkRenderPassCreateInfo rpci = {};
12176 rpci.subpassCount = 1;
12177 rpci.pSubpasses = &subpass;
12178 rpci.attachmentCount = 1;
12179 VkAttachmentDescription attach_desc = {};
12180 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12181 // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
12182 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
12183 rpci.pAttachments = &attach_desc;
12184 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12186 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12187 VkPipelineObj pipe(m_device);
12188 pipe.AddShader(&vs);
12189 pipe.AddShader(&fs);
12190 pipe.AddColorAttachment();
12191 VkViewport view_port = {};
12192 m_viewports.push_back(view_port);
12193 pipe.SetViewport(m_viewports);
12194 VkRect2D rect = {};
12195 m_scissors.push_back(rect);
12196 pipe.SetScissor(m_scissors);
12197 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12199 VkCommandBufferInheritanceInfo cbii = {};
12200 cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12201 cbii.renderPass = rp;
12203 VkCommandBufferBeginInfo cbbi = {};
12204 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12205 cbbi.pInheritanceInfo = &cbii;
12206 vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
12207 VkRenderPassBeginInfo rpbi = {};
12208 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
12209 rpbi.framebuffer = m_framebuffer;
12210 rpbi.renderPass = rp;
12211 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
12212 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline ");
12215 // Render triangle (the error should trigger on the attempt to draw).
12218 // Finalize recording of the command buffer
12219 EndCommandBuffer();
12221 m_errorMonitor->VerifyFound();
12223 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12224 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12225 vkDestroyRenderPass(m_device->device(), rp, NULL);
12228 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
12229 // Create Pipeline where the number of blend attachments doesn't match the
12230 // number of color attachments. In this case, we don't add any color
12231 // blend attachments even though we have a color attachment.
12234 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12235 "Render pass subpass 0 mismatch with blending state defined and blend state attachment");
12237 ASSERT_NO_FATAL_FAILURE(InitState());
12238 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12239 VkDescriptorPoolSize ds_type_count = {};
12240 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12241 ds_type_count.descriptorCount = 1;
12243 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12244 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12245 ds_pool_ci.pNext = NULL;
12246 ds_pool_ci.maxSets = 1;
12247 ds_pool_ci.poolSizeCount = 1;
12248 ds_pool_ci.pPoolSizes = &ds_type_count;
12250 VkDescriptorPool ds_pool;
12251 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12252 ASSERT_VK_SUCCESS(err);
12254 VkDescriptorSetLayoutBinding dsl_binding = {};
12255 dsl_binding.binding = 0;
12256 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12257 dsl_binding.descriptorCount = 1;
12258 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12259 dsl_binding.pImmutableSamplers = NULL;
12261 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12262 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12263 ds_layout_ci.pNext = NULL;
12264 ds_layout_ci.bindingCount = 1;
12265 ds_layout_ci.pBindings = &dsl_binding;
12267 VkDescriptorSetLayout ds_layout;
12268 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12269 ASSERT_VK_SUCCESS(err);
12271 VkDescriptorSet descriptorSet;
12272 VkDescriptorSetAllocateInfo alloc_info = {};
12273 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12274 alloc_info.descriptorSetCount = 1;
12275 alloc_info.descriptorPool = ds_pool;
12276 alloc_info.pSetLayouts = &ds_layout;
12277 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12278 ASSERT_VK_SUCCESS(err);
12280 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12281 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12282 pipe_ms_state_ci.pNext = NULL;
12283 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12284 pipe_ms_state_ci.sampleShadingEnable = 0;
12285 pipe_ms_state_ci.minSampleShading = 1.0;
12286 pipe_ms_state_ci.pSampleMask = NULL;
12288 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12289 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12290 pipeline_layout_ci.pNext = NULL;
12291 pipeline_layout_ci.setLayoutCount = 1;
12292 pipeline_layout_ci.pSetLayouts = &ds_layout;
12294 VkPipelineLayout pipeline_layout;
12295 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12296 ASSERT_VK_SUCCESS(err);
12298 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12299 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12300 // but add it to be able to run on more devices
12301 VkPipelineObj pipe(m_device);
12302 pipe.AddShader(&vs);
12303 pipe.AddShader(&fs);
12304 pipe.SetMSAA(&pipe_ms_state_ci);
12305 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12307 BeginCommandBuffer();
12308 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12310 // Render triangle (the error should trigger on the attempt to draw).
12313 // Finalize recording of the command buffer
12314 EndCommandBuffer();
12316 m_errorMonitor->VerifyFound();
12318 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12319 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12320 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12323 TEST_F(VkLayerTest, MissingClearAttachment) {
12324 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
12325 "structure passed to vkCmdClearAttachments");
12326 ASSERT_NO_FATAL_FAILURE(InitState());
12327 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12328 "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored");
12330 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
12331 m_errorMonitor->VerifyFound();
12334 TEST_F(VkLayerTest, ClearCmdNoDraw) {
12335 // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
12336 // to issuing a Draw
12339 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12340 "vkCmdClearAttachments() issued on CB object ");
12342 ASSERT_NO_FATAL_FAILURE(InitState());
12343 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12345 VkDescriptorPoolSize ds_type_count = {};
12346 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12347 ds_type_count.descriptorCount = 1;
12349 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12350 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12351 ds_pool_ci.pNext = NULL;
12352 ds_pool_ci.maxSets = 1;
12353 ds_pool_ci.poolSizeCount = 1;
12354 ds_pool_ci.pPoolSizes = &ds_type_count;
12356 VkDescriptorPool ds_pool;
12357 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12358 ASSERT_VK_SUCCESS(err);
12360 VkDescriptorSetLayoutBinding dsl_binding = {};
12361 dsl_binding.binding = 0;
12362 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12363 dsl_binding.descriptorCount = 1;
12364 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12365 dsl_binding.pImmutableSamplers = NULL;
12367 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12368 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12369 ds_layout_ci.pNext = NULL;
12370 ds_layout_ci.bindingCount = 1;
12371 ds_layout_ci.pBindings = &dsl_binding;
12373 VkDescriptorSetLayout ds_layout;
12374 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12375 ASSERT_VK_SUCCESS(err);
12377 VkDescriptorSet descriptorSet;
12378 VkDescriptorSetAllocateInfo alloc_info = {};
12379 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12380 alloc_info.descriptorSetCount = 1;
12381 alloc_info.descriptorPool = ds_pool;
12382 alloc_info.pSetLayouts = &ds_layout;
12383 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12384 ASSERT_VK_SUCCESS(err);
12386 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12387 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12388 pipe_ms_state_ci.pNext = NULL;
12389 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12390 pipe_ms_state_ci.sampleShadingEnable = 0;
12391 pipe_ms_state_ci.minSampleShading = 1.0;
12392 pipe_ms_state_ci.pSampleMask = NULL;
12394 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12395 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12396 pipeline_layout_ci.pNext = NULL;
12397 pipeline_layout_ci.setLayoutCount = 1;
12398 pipeline_layout_ci.pSetLayouts = &ds_layout;
12400 VkPipelineLayout pipeline_layout;
12401 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12402 ASSERT_VK_SUCCESS(err);
12404 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12405 // We shouldn't need a fragment shader but add it to be able to run
12407 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12409 VkPipelineObj pipe(m_device);
12410 pipe.AddShader(&vs);
12411 pipe.AddShader(&fs);
12412 pipe.SetMSAA(&pipe_ms_state_ci);
12413 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12415 BeginCommandBuffer();
12417 // Main thing we care about for this test is that the VkImage obj we're
12418 // clearing matches Color Attachment of FB
12419 // Also pass down other dummy params to keep driver and paramchecker happy
12420 VkClearAttachment color_attachment;
12421 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12422 color_attachment.clearValue.color.float32[0] = 1.0;
12423 color_attachment.clearValue.color.float32[1] = 1.0;
12424 color_attachment.clearValue.color.float32[2] = 1.0;
12425 color_attachment.clearValue.color.float32[3] = 1.0;
12426 color_attachment.colorAttachment = 0;
12427 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}};
12429 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
12431 m_errorMonitor->VerifyFound();
12433 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12434 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12435 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12438 TEST_F(VkLayerTest, VtxBufferBadIndex) {
12441 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12442 "but no vertex buffers are attached to this Pipeline State Object");
12444 ASSERT_NO_FATAL_FAILURE(InitState());
12445 ASSERT_NO_FATAL_FAILURE(InitViewport());
12446 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12448 VkDescriptorPoolSize ds_type_count = {};
12449 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12450 ds_type_count.descriptorCount = 1;
12452 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12453 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12454 ds_pool_ci.pNext = NULL;
12455 ds_pool_ci.maxSets = 1;
12456 ds_pool_ci.poolSizeCount = 1;
12457 ds_pool_ci.pPoolSizes = &ds_type_count;
12459 VkDescriptorPool ds_pool;
12460 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12461 ASSERT_VK_SUCCESS(err);
12463 VkDescriptorSetLayoutBinding dsl_binding = {};
12464 dsl_binding.binding = 0;
12465 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12466 dsl_binding.descriptorCount = 1;
12467 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12468 dsl_binding.pImmutableSamplers = NULL;
12470 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12471 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12472 ds_layout_ci.pNext = NULL;
12473 ds_layout_ci.bindingCount = 1;
12474 ds_layout_ci.pBindings = &dsl_binding;
12476 VkDescriptorSetLayout ds_layout;
12477 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12478 ASSERT_VK_SUCCESS(err);
12480 VkDescriptorSet descriptorSet;
12481 VkDescriptorSetAllocateInfo alloc_info = {};
12482 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12483 alloc_info.descriptorSetCount = 1;
12484 alloc_info.descriptorPool = ds_pool;
12485 alloc_info.pSetLayouts = &ds_layout;
12486 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12487 ASSERT_VK_SUCCESS(err);
12489 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12490 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12491 pipe_ms_state_ci.pNext = NULL;
12492 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12493 pipe_ms_state_ci.sampleShadingEnable = 0;
12494 pipe_ms_state_ci.minSampleShading = 1.0;
12495 pipe_ms_state_ci.pSampleMask = NULL;
12497 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12498 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12499 pipeline_layout_ci.pNext = NULL;
12500 pipeline_layout_ci.setLayoutCount = 1;
12501 pipeline_layout_ci.pSetLayouts = &ds_layout;
12502 VkPipelineLayout pipeline_layout;
12504 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12505 ASSERT_VK_SUCCESS(err);
12507 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12508 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12509 // but add it to be able to run on more devices
12510 VkPipelineObj pipe(m_device);
12511 pipe.AddShader(&vs);
12512 pipe.AddShader(&fs);
12513 pipe.AddColorAttachment();
12514 pipe.SetMSAA(&pipe_ms_state_ci);
12515 pipe.SetViewport(m_viewports);
12516 pipe.SetScissor(m_scissors);
12517 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12519 BeginCommandBuffer();
12520 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12521 // Don't care about actual data, just need to get to draw to flag error
12522 static const float vbo_data[3] = {1.f, 0.f, 1.f};
12523 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data);
12524 BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
12527 m_errorMonitor->VerifyFound();
12529 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12530 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12531 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12534 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
12535 TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call."
12536 "Use invalid Queue Family Index in vkCreateDevice");
12537 ASSERT_NO_FATAL_FAILURE(InitState());
12539 const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() "
12540 "w/ pPhysicalDeviceCount value ";
12542 const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid "
12543 "queueFamilyIndex ";
12545 const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #";
12547 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message);
12548 // The following test fails with recent NVidia drivers.
12549 // By the time core_validation is reached, the NVidia
12550 // driver has sanitized the invalid condition and core_validation
12551 // is not introduced to the failure condition. This is not the case
12552 // with AMD and Mesa drivers. Futher investigation is required
12553 // uint32_t count = static_cast<uint32_t>(~0);
12554 // VkPhysicalDevice physical_device;
12555 // vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
12556 // m_errorMonitor->VerifyFound();
12558 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message);
12559 float queue_priority = 0.0;
12561 VkDeviceQueueCreateInfo queue_create_info = {};
12562 queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
12563 queue_create_info.queueCount = 1;
12564 queue_create_info.pQueuePriorities = &queue_priority;
12565 queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
12567 VkPhysicalDeviceFeatures features = m_device->phy().features();
12568 VkDevice testDevice;
12569 VkDeviceCreateInfo device_create_info = {};
12570 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
12571 device_create_info.queueCreateInfoCount = 1;
12572 device_create_info.pQueueCreateInfos = &queue_create_info;
12573 device_create_info.pEnabledFeatures = &features;
12574 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12575 m_errorMonitor->VerifyFound();
12577 queue_create_info.queueFamilyIndex = 1;
12579 unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
12580 VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
12581 for (unsigned i = 0; i < feature_count; i++) {
12582 if (VK_FALSE == feature_array[i]) {
12583 feature_array[i] = VK_TRUE;
12584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message);
12585 device_create_info.pEnabledFeatures = &features;
12586 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12587 m_errorMonitor->VerifyFound();
12593 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) {
12594 TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call."
12595 "End a command buffer with a query still in progress.");
12597 const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one "
12598 "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both "
12601 const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
12603 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index);
12605 ASSERT_NO_FATAL_FAILURE(InitState());
12608 VkEventCreateInfo event_create_info{};
12609 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12610 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12612 VkQueue queue = VK_NULL_HANDLE;
12613 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
12615 BeginCommandBuffer();
12617 VkImageObj image(m_device);
12618 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12619 ASSERT_TRUE(image.initialized());
12620 VkImageMemoryBarrier img_barrier = {};
12621 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
12622 img_barrier.pNext = NULL;
12623 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
12624 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
12625 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12626 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12627 img_barrier.image = image.handle();
12628 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
12630 // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies
12631 // that layer validation catches the case when it is not.
12632 img_barrier.dstQueueFamilyIndex = 0;
12633 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12634 img_barrier.subresourceRange.baseArrayLayer = 0;
12635 img_barrier.subresourceRange.baseMipLevel = 0;
12636 img_barrier.subresourceRange.layerCount = 1;
12637 img_barrier.subresourceRange.levelCount = 1;
12638 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
12639 nullptr, 0, nullptr, 1, &img_barrier);
12640 m_errorMonitor->VerifyFound();
12642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
12644 VkQueryPool query_pool;
12645 VkQueryPoolCreateInfo query_pool_create_info = {};
12646 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
12647 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
12648 query_pool_create_info.queryCount = 1;
12649 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12651 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
12652 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12654 vkEndCommandBuffer(m_commandBuffer->handle());
12655 m_errorMonitor->VerifyFound();
12657 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
12658 vkDestroyEvent(m_device->device(), event, nullptr);
12661 TEST_F(VkLayerTest, VertexBufferInvalid) {
12662 TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
12663 "delete a buffer twice, use an invalid offset for each "
12664 "buffer type, and attempt to bind a null buffer");
12666 const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
12667 "using deleted buffer ";
12668 const char *double_destroy_message = "Cannot free buffer 0x";
12669 const char *invalid_offset_message = "vkBindBufferMemory(): "
12670 "memoryOffset is 0x";
12671 const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
12672 "storage memoryOffset "
12674 const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
12675 "texel memoryOffset "
12677 const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
12678 "uniform memoryOffset "
12680 const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
12682 const char *free_invalid_buffer_message = "Request to delete memory "
12685 ASSERT_NO_FATAL_FAILURE(InitState());
12686 ASSERT_NO_FATAL_FAILURE(InitViewport());
12687 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12689 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12690 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12691 pipe_ms_state_ci.pNext = NULL;
12692 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12693 pipe_ms_state_ci.sampleShadingEnable = 0;
12694 pipe_ms_state_ci.minSampleShading = 1.0;
12695 pipe_ms_state_ci.pSampleMask = nullptr;
12697 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12698 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12699 VkPipelineLayout pipeline_layout;
12701 VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout);
12702 ASSERT_VK_SUCCESS(err);
12704 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12705 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12706 VkPipelineObj pipe(m_device);
12707 pipe.AddShader(&vs);
12708 pipe.AddShader(&fs);
12709 pipe.AddColorAttachment();
12710 pipe.SetMSAA(&pipe_ms_state_ci);
12711 pipe.SetViewport(m_viewports);
12712 pipe.SetScissor(m_scissors);
12713 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12715 BeginCommandBuffer();
12716 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12719 // Create and bind a vertex buffer in a reduced scope, which will cause
12720 // it to be deleted upon leaving this scope
12721 const float vbo_data[3] = {1.f, 0.f, 1.f};
12722 VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data);
12723 draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
12724 draw_verticies.AddVertexInputToPipe(pipe);
12729 EndCommandBuffer();
12731 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
12732 QueueCommandBuffer(false);
12733 m_errorMonitor->VerifyFound();
12736 // Create and bind a vertex buffer in a reduced scope, and delete it
12737 // twice, the second through the destructor
12738 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
12739 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message);
12740 buffer_test.TestDoubleDestroy();
12742 m_errorMonitor->VerifyFound();
12744 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
12745 // Create and bind a memory buffer with an invalid offset.
12746 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
12747 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
12749 m_errorMonitor->VerifyFound();
12752 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
12753 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
12754 // Create and bind a memory buffer with an invalid offset again,
12755 // but look for a texel buffer message.
12756 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
12757 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12759 m_errorMonitor->VerifyFound();
12762 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
12763 // Create and bind a memory buffer with an invalid offset again, but
12764 // look for a uniform buffer message.
12765 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
12766 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12768 m_errorMonitor->VerifyFound();
12771 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
12772 // Create and bind a memory buffer with an invalid offset again, but
12773 // look for a storage buffer message.
12774 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
12775 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12777 m_errorMonitor->VerifyFound();
12781 // Attempt to bind a null buffer.
12782 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message);
12783 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer);
12785 m_errorMonitor->VerifyFound();
12789 // Attempt to use an invalid handle to delete a buffer.
12790 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message);
12791 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
12794 m_errorMonitor->VerifyFound();
12796 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12799 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
12800 TEST_F(VkLayerTest, InvalidImageLayout) {
12801 TEST_DESCRIPTION("Hit all possible validation checks associated with the "
12802 "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having"
12803 "images in the wrong layout when they're copied or transitioned.");
12804 // 3 in ValidateCmdBufImageLayouts
12805 // * -1 Attempt to submit cmd buf w/ deleted image
12806 // * -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
12807 // * -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
12808 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12809 "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
12811 ASSERT_NO_FATAL_FAILURE(InitState());
12812 // Create src & dst images to use for copy operations
12816 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
12817 const int32_t tex_width = 32;
12818 const int32_t tex_height = 32;
12820 VkImageCreateInfo image_create_info = {};
12821 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
12822 image_create_info.pNext = NULL;
12823 image_create_info.imageType = VK_IMAGE_TYPE_2D;
12824 image_create_info.format = tex_format;
12825 image_create_info.extent.width = tex_width;
12826 image_create_info.extent.height = tex_height;
12827 image_create_info.extent.depth = 1;
12828 image_create_info.mipLevels = 1;
12829 image_create_info.arrayLayers = 4;
12830 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
12831 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
12832 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
12833 image_create_info.flags = 0;
12835 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
12836 ASSERT_VK_SUCCESS(err);
12837 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
12838 ASSERT_VK_SUCCESS(err);
12840 BeginCommandBuffer();
12841 VkImageCopy copyRegion;
12842 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12843 copyRegion.srcSubresource.mipLevel = 0;
12844 copyRegion.srcSubresource.baseArrayLayer = 0;
12845 copyRegion.srcSubresource.layerCount = 1;
12846 copyRegion.srcOffset.x = 0;
12847 copyRegion.srcOffset.y = 0;
12848 copyRegion.srcOffset.z = 0;
12849 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12850 copyRegion.dstSubresource.mipLevel = 0;
12851 copyRegion.dstSubresource.baseArrayLayer = 0;
12852 copyRegion.dstSubresource.layerCount = 1;
12853 copyRegion.dstOffset.x = 0;
12854 copyRegion.dstOffset.y = 0;
12855 copyRegion.dstOffset.z = 0;
12856 copyRegion.extent.width = 1;
12857 copyRegion.extent.height = 1;
12858 copyRegion.extent.depth = 1;
12859 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12860 m_errorMonitor->VerifyFound();
12861 // Now cause error due to src image layout changing
12862 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is "
12863 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12864 "layout VK_IMAGE_LAYOUT_GENERAL.");
12865 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12866 m_errorMonitor->VerifyFound();
12867 // Final src error is due to bad layout type
12868 m_errorMonitor->SetDesiredFailureMsg(
12869 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12870 "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL.");
12871 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12872 m_errorMonitor->VerifyFound();
12873 // Now verify same checks for dst
12874 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12875 "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
12876 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12877 m_errorMonitor->VerifyFound();
12878 // Now cause error due to src image layout changing
12879 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is "
12880 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12881 "layout VK_IMAGE_LAYOUT_GENERAL.");
12882 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region);
12883 m_errorMonitor->VerifyFound();
12884 m_errorMonitor->SetDesiredFailureMsg(
12885 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12886 "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL.");
12887 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region);
12888 m_errorMonitor->VerifyFound();
12889 // Now cause error due to bad image layout transition in PipelineBarrier
12890 VkImageMemoryBarrier image_barrier[1] = {};
12891 image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12892 image_barrier[0].image = src_image;
12893 image_barrier[0].subresourceRange.layerCount = 2;
12894 image_barrier[0].subresourceRange.levelCount = 2;
12895 image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12896 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from "
12897 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when "
12898 "current layout is VK_IMAGE_LAYOUT_GENERAL.");
12899 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
12900 NULL, 0, NULL, 1, image_barrier);
12901 m_errorMonitor->VerifyFound();
12903 // Finally some layout errors at RenderPass create time
12904 // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
12905 VkAttachmentReference attach = {};
12906 // perf warning for GENERAL layout w/ non-DS input attachment
12907 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12908 VkSubpassDescription subpass = {};
12909 subpass.inputAttachmentCount = 1;
12910 subpass.pInputAttachments = &attach;
12911 VkRenderPassCreateInfo rpci = {};
12912 rpci.subpassCount = 1;
12913 rpci.pSubpasses = &subpass;
12914 rpci.attachmentCount = 1;
12915 VkAttachmentDescription attach_desc = {};
12916 attach_desc.format = VK_FORMAT_UNDEFINED;
12917 rpci.pAttachments = &attach_desc;
12918 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12920 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12921 "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
12922 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12923 m_errorMonitor->VerifyFound();
12924 // error w/ non-general layout
12925 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12927 m_errorMonitor->SetDesiredFailureMsg(
12928 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12929 "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
12930 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12931 m_errorMonitor->VerifyFound();
12932 subpass.inputAttachmentCount = 0;
12933 subpass.colorAttachmentCount = 1;
12934 subpass.pColorAttachments = &attach;
12935 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12936 // perf warning for GENERAL layout on color attachment
12937 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12938 "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
12939 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12940 m_errorMonitor->VerifyFound();
12941 // error w/ non-color opt or GENERAL layout for color attachment
12942 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12943 m_errorMonitor->SetDesiredFailureMsg(
12944 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12945 "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
12946 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12947 m_errorMonitor->VerifyFound();
12948 subpass.colorAttachmentCount = 0;
12949 subpass.pDepthStencilAttachment = &attach;
12950 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12951 // perf warning for GENERAL layout on DS attachment
12952 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12953 "GENERAL layout for depth attachment may not give optimal performance.");
12954 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12955 m_errorMonitor->VerifyFound();
12956 // error w/ non-ds opt or GENERAL layout for color attachment
12957 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12958 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12959 "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
12960 "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
12961 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12962 m_errorMonitor->VerifyFound();
12963 // For this error we need a valid renderpass so create default one
12964 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12965 attach.attachment = 0;
12966 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
12967 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12968 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
12969 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
12970 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
12971 // Can't do a CLEAR load on READ_ONLY initialLayout
12972 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
12973 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12974 attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12975 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout "
12976 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_"
12978 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12979 m_errorMonitor->VerifyFound();
12981 vkDestroyImage(m_device->device(), src_image, NULL);
12982 vkDestroyImage(m_device->device(), dst_image, NULL);
12985 TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
12986 TEST_DESCRIPTION("Positive test where we create a renderpass with an "
12987 "attachment that uses LOAD_OP_CLEAR, the first subpass "
12988 "has a valid layout, and a second subpass then uses a "
12989 "valid *READ_ONLY* layout.");
12990 m_errorMonitor->ExpectSuccess();
12991 ASSERT_NO_FATAL_FAILURE(InitState());
12993 VkAttachmentReference attach[2] = {};
12994 attach[0].attachment = 0;
12995 attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
12996 attach[1].attachment = 0;
12997 attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12998 VkSubpassDescription subpasses[2] = {};
12999 // First subpass clears DS attach on load
13000 subpasses[0].pDepthStencilAttachment = &attach[0];
13001 // 2nd subpass reads in DS as input attachment
13002 subpasses[1].inputAttachmentCount = 1;
13003 subpasses[1].pInputAttachments = &attach[1];
13004 VkAttachmentDescription attach_desc = {};
13005 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
13006 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
13007 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
13008 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
13009 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13010 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13011 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13012 attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13013 VkRenderPassCreateInfo rpci = {};
13014 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
13015 rpci.attachmentCount = 1;
13016 rpci.pAttachments = &attach_desc;
13017 rpci.subpassCount = 2;
13018 rpci.pSubpasses = subpasses;
13020 // Now create RenderPass and verify no errors
13022 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
13023 m_errorMonitor->VerifyNotFound();
13025 vkDestroyRenderPass(m_device->device(), rp, NULL);
13028 TEST_F(VkLayerTest, SimultaneousUse) {
13029 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13030 "in primary and secondary command buffers.");
13032 ASSERT_NO_FATAL_FAILURE(InitState());
13033 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13035 const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
13036 const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
13037 "will cause primary command buffer";
13039 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
13040 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13041 command_buffer_allocate_info.commandPool = m_commandPool;
13042 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13043 command_buffer_allocate_info.commandBufferCount = 1;
13045 VkCommandBuffer secondary_command_buffer;
13046 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
13047 VkCommandBufferBeginInfo command_buffer_begin_info = {};
13048 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
13049 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
13050 command_buffer_inheritance_info.renderPass = m_renderPass;
13051 command_buffer_inheritance_info.framebuffer = m_framebuffer;
13052 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13053 command_buffer_begin_info.flags =
13054 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13055 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
13057 vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
13058 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13059 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13060 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13061 vkEndCommandBuffer(secondary_command_buffer);
13063 VkSubmitInfo submit_info = {};
13064 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13065 submit_info.commandBufferCount = 1;
13066 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13067 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13069 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13070 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13071 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1);
13072 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13073 m_errorMonitor->VerifyFound();
13074 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13075 vkEndCommandBuffer(m_commandBuffer->handle());
13077 m_errorMonitor->SetDesiredFailureMsg(0, "");
13078 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13080 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
13081 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13082 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2);
13085 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13086 m_errorMonitor->VerifyFound();
13087 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13088 vkEndCommandBuffer(m_commandBuffer->handle());
13091 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
13092 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13093 "in primary and secondary command buffers. "
13094 "Delete objects that are inuse. Call VkQueueSubmit "
13095 "with an event that has been deleted.");
13097 ASSERT_NO_FATAL_FAILURE(InitState());
13098 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13100 const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x";
13101 const char *cannot_delete_event_message = "Cannot delete event 0x";
13102 const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x";
13103 const char *cannot_destroy_fence_message = "Fence 0x";
13105 BeginCommandBuffer();
13108 VkEventCreateInfo event_create_info = {};
13109 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
13110 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13111 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13113 EndCommandBuffer();
13114 vkDestroyEvent(m_device->device(), event, nullptr);
13116 VkSubmitInfo submit_info = {};
13117 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13118 submit_info.commandBufferCount = 1;
13119 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13120 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message);
13121 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13122 m_errorMonitor->VerifyFound();
13124 m_errorMonitor->SetDesiredFailureMsg(0, "");
13125 vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13127 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13129 VkSemaphoreCreateInfo semaphore_create_info = {};
13130 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13131 VkSemaphore semaphore;
13132 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13133 VkFenceCreateInfo fence_create_info = {};
13134 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13136 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13138 VkDescriptorPoolSize descriptor_pool_type_count = {};
13139 descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13140 descriptor_pool_type_count.descriptorCount = 1;
13142 VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
13143 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13144 descriptor_pool_create_info.maxSets = 1;
13145 descriptor_pool_create_info.poolSizeCount = 1;
13146 descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
13147 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
13149 VkDescriptorPool descriptorset_pool;
13150 ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
13152 VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
13153 descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13154 descriptorset_layout_binding.descriptorCount = 1;
13155 descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
13157 VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
13158 descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13159 descriptorset_layout_create_info.bindingCount = 1;
13160 descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
13162 VkDescriptorSetLayout descriptorset_layout;
13164 vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
13166 VkDescriptorSet descriptorset;
13167 VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
13168 descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13169 descriptorset_allocate_info.descriptorSetCount = 1;
13170 descriptorset_allocate_info.descriptorPool = descriptorset_pool;
13171 descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
13172 ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
13174 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
13176 VkDescriptorBufferInfo buffer_info = {};
13177 buffer_info.buffer = buffer_test.GetBuffer();
13178 buffer_info.offset = 0;
13179 buffer_info.range = 1024;
13181 VkWriteDescriptorSet write_descriptor_set = {};
13182 write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13183 write_descriptor_set.dstSet = descriptorset;
13184 write_descriptor_set.descriptorCount = 1;
13185 write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13186 write_descriptor_set.pBufferInfo = &buffer_info;
13188 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
13190 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13191 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13193 VkPipelineObj pipe(m_device);
13194 pipe.AddColorAttachment();
13195 pipe.AddShader(&vs);
13196 pipe.AddShader(&fs);
13198 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
13199 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13200 pipeline_layout_create_info.setLayoutCount = 1;
13201 pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
13203 VkPipelineLayout pipeline_layout;
13204 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
13206 pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
13208 BeginCommandBuffer();
13209 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13211 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13212 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13213 &descriptorset, 0, NULL);
13215 EndCommandBuffer();
13217 submit_info.signalSemaphoreCount = 1;
13218 submit_info.pSignalSemaphores = &semaphore;
13219 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
13221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message);
13222 vkDestroyEvent(m_device->device(), event, nullptr);
13223 m_errorMonitor->VerifyFound();
13225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message);
13226 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13227 m_errorMonitor->VerifyFound();
13229 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message);
13230 vkDestroyFence(m_device->device(), fence, nullptr);
13231 m_errorMonitor->VerifyFound();
13233 vkQueueWaitIdle(m_device->m_queue);
13234 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13235 vkDestroyFence(m_device->device(), fence, nullptr);
13236 vkDestroyEvent(m_device->device(), event, nullptr);
13237 vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
13238 vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
13239 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
13242 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
13243 TEST_DESCRIPTION("Delete in-use query pool.");
13245 ASSERT_NO_FATAL_FAILURE(InitState());
13246 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13248 VkQueryPool query_pool;
13249 VkQueryPoolCreateInfo query_pool_ci{};
13250 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
13251 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
13252 query_pool_ci.queryCount = 1;
13253 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13254 BeginCommandBuffer();
13255 // Reset query pool to create binding with cmd buffer
13256 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13258 EndCommandBuffer();
13260 VkSubmitInfo submit_info = {};
13261 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13262 submit_info.commandBufferCount = 1;
13263 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13264 // Submit cmd buffer and then destroy query pool while in-flight
13265 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13267 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x");
13268 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13269 m_errorMonitor->VerifyFound();
13271 vkQueueWaitIdle(m_device->m_queue);
13272 // Now that cmd buffer done we can safely destroy query_pool
13273 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13276 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
13277 TEST_DESCRIPTION("Delete in-use pipeline.");
13279 ASSERT_NO_FATAL_FAILURE(InitState());
13280 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13282 // Empty pipeline layout used for binding PSO
13283 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13284 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13285 pipeline_layout_ci.setLayoutCount = 0;
13286 pipeline_layout_ci.pSetLayouts = NULL;
13288 VkPipelineLayout pipeline_layout;
13289 VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout);
13290 ASSERT_VK_SUCCESS(err);
13292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x");
13293 // Create PSO to be used for draw-time errors below
13294 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13295 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13296 // Store pipeline handle so we can actually delete it before test finishes
13297 VkPipeline delete_this_pipeline;
13298 { // Scope pipeline so it will be auto-deleted
13299 VkPipelineObj pipe(m_device);
13300 pipe.AddShader(&vs);
13301 pipe.AddShader(&fs);
13302 pipe.AddColorAttachment();
13303 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13304 delete_this_pipeline = pipe.handle();
13306 BeginCommandBuffer();
13307 // Bind pipeline to cmd buffer
13308 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13310 EndCommandBuffer();
13312 VkSubmitInfo submit_info = {};
13313 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13314 submit_info.commandBufferCount = 1;
13315 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13316 // Submit cmd buffer and then pipeline destroyed while in-flight
13317 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13318 } // Pipeline deletion triggered here
13319 m_errorMonitor->VerifyFound();
13320 // Make sure queue finished and then actually delete pipeline
13321 vkQueueWaitIdle(m_device->m_queue);
13322 vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
13323 vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
13326 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
13327 TEST_DESCRIPTION("Delete in-use imageView.");
13329 ASSERT_NO_FATAL_FAILURE(InitState());
13330 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13332 VkDescriptorPoolSize ds_type_count;
13333 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13334 ds_type_count.descriptorCount = 1;
13336 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13337 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13338 ds_pool_ci.maxSets = 1;
13339 ds_pool_ci.poolSizeCount = 1;
13340 ds_pool_ci.pPoolSizes = &ds_type_count;
13342 VkDescriptorPool ds_pool;
13343 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13344 ASSERT_VK_SUCCESS(err);
13346 VkSamplerCreateInfo sampler_ci = {};
13347 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13348 sampler_ci.pNext = NULL;
13349 sampler_ci.magFilter = VK_FILTER_NEAREST;
13350 sampler_ci.minFilter = VK_FILTER_NEAREST;
13351 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13352 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13353 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13354 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13355 sampler_ci.mipLodBias = 1.0;
13356 sampler_ci.anisotropyEnable = VK_FALSE;
13357 sampler_ci.maxAnisotropy = 1;
13358 sampler_ci.compareEnable = VK_FALSE;
13359 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13360 sampler_ci.minLod = 1.0;
13361 sampler_ci.maxLod = 1.0;
13362 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13363 sampler_ci.unnormalizedCoordinates = VK_FALSE;
13366 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13367 ASSERT_VK_SUCCESS(err);
13369 VkDescriptorSetLayoutBinding layout_binding;
13370 layout_binding.binding = 0;
13371 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13372 layout_binding.descriptorCount = 1;
13373 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13374 layout_binding.pImmutableSamplers = NULL;
13376 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13377 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13378 ds_layout_ci.bindingCount = 1;
13379 ds_layout_ci.pBindings = &layout_binding;
13380 VkDescriptorSetLayout ds_layout;
13381 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13382 ASSERT_VK_SUCCESS(err);
13384 VkDescriptorSetAllocateInfo alloc_info = {};
13385 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13386 alloc_info.descriptorSetCount = 1;
13387 alloc_info.descriptorPool = ds_pool;
13388 alloc_info.pSetLayouts = &ds_layout;
13389 VkDescriptorSet descriptor_set;
13390 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13391 ASSERT_VK_SUCCESS(err);
13393 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13394 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13395 pipeline_layout_ci.pNext = NULL;
13396 pipeline_layout_ci.setLayoutCount = 1;
13397 pipeline_layout_ci.pSetLayouts = &ds_layout;
13399 VkPipelineLayout pipeline_layout;
13400 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13401 ASSERT_VK_SUCCESS(err);
13403 VkImageObj image(m_device);
13404 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13405 ASSERT_TRUE(image.initialized());
13408 VkImageViewCreateInfo ivci = {};
13409 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13410 ivci.image = image.handle();
13411 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13412 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13413 ivci.subresourceRange.layerCount = 1;
13414 ivci.subresourceRange.baseMipLevel = 0;
13415 ivci.subresourceRange.levelCount = 1;
13416 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13418 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13419 ASSERT_VK_SUCCESS(err);
13421 VkDescriptorImageInfo image_info{};
13422 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13423 image_info.imageView = view;
13424 image_info.sampler = sampler;
13426 VkWriteDescriptorSet descriptor_write = {};
13427 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13428 descriptor_write.dstSet = descriptor_set;
13429 descriptor_write.dstBinding = 0;
13430 descriptor_write.descriptorCount = 1;
13431 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13432 descriptor_write.pImageInfo = &image_info;
13434 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13436 // Create PSO to use the sampler
13437 char const *vsSource = "#version 450\n"
13439 "out gl_PerVertex { \n"
13440 " vec4 gl_Position;\n"
13443 " gl_Position = vec4(1);\n"
13445 char const *fsSource = "#version 450\n"
13447 "layout(set=0, binding=0) uniform sampler2D s;\n"
13448 "layout(location=0) out vec4 x;\n"
13450 " x = texture(s, vec2(1));\n"
13452 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13453 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13454 VkPipelineObj pipe(m_device);
13455 pipe.AddShader(&vs);
13456 pipe.AddShader(&fs);
13457 pipe.AddColorAttachment();
13458 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13460 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
13462 BeginCommandBuffer();
13463 // Bind pipeline to cmd buffer
13464 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13465 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13466 &descriptor_set, 0, nullptr);
13468 EndCommandBuffer();
13469 // Submit cmd buffer then destroy sampler
13470 VkSubmitInfo submit_info = {};
13471 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13472 submit_info.commandBufferCount = 1;
13473 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13474 // Submit cmd buffer and then destroy imageView while in-flight
13475 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13477 vkDestroyImageView(m_device->device(), view, nullptr);
13478 m_errorMonitor->VerifyFound();
13479 vkQueueWaitIdle(m_device->m_queue);
13480 // Now we can actually destroy imageView
13481 vkDestroyImageView(m_device->device(), view, NULL);
13482 vkDestroySampler(m_device->device(), sampler, nullptr);
13483 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13484 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13485 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13488 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
13489 TEST_DESCRIPTION("Delete in-use bufferView.");
13491 ASSERT_NO_FATAL_FAILURE(InitState());
13492 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13494 VkDescriptorPoolSize ds_type_count;
13495 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13496 ds_type_count.descriptorCount = 1;
13498 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13499 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13500 ds_pool_ci.maxSets = 1;
13501 ds_pool_ci.poolSizeCount = 1;
13502 ds_pool_ci.pPoolSizes = &ds_type_count;
13504 VkDescriptorPool ds_pool;
13505 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13506 ASSERT_VK_SUCCESS(err);
13508 VkDescriptorSetLayoutBinding layout_binding;
13509 layout_binding.binding = 0;
13510 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13511 layout_binding.descriptorCount = 1;
13512 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13513 layout_binding.pImmutableSamplers = NULL;
13515 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13516 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13517 ds_layout_ci.bindingCount = 1;
13518 ds_layout_ci.pBindings = &layout_binding;
13519 VkDescriptorSetLayout ds_layout;
13520 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13521 ASSERT_VK_SUCCESS(err);
13523 VkDescriptorSetAllocateInfo alloc_info = {};
13524 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13525 alloc_info.descriptorSetCount = 1;
13526 alloc_info.descriptorPool = ds_pool;
13527 alloc_info.pSetLayouts = &ds_layout;
13528 VkDescriptorSet descriptor_set;
13529 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13530 ASSERT_VK_SUCCESS(err);
13532 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13533 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13534 pipeline_layout_ci.pNext = NULL;
13535 pipeline_layout_ci.setLayoutCount = 1;
13536 pipeline_layout_ci.pSetLayouts = &ds_layout;
13538 VkPipelineLayout pipeline_layout;
13539 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13540 ASSERT_VK_SUCCESS(err);
13543 uint32_t queue_family_index = 0;
13544 VkBufferCreateInfo buffer_create_info = {};
13545 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
13546 buffer_create_info.size = 1024;
13547 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
13548 buffer_create_info.queueFamilyIndexCount = 1;
13549 buffer_create_info.pQueueFamilyIndices = &queue_family_index;
13551 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
13552 ASSERT_VK_SUCCESS(err);
13554 VkMemoryRequirements memory_reqs;
13555 VkDeviceMemory buffer_memory;
13557 VkMemoryAllocateInfo memory_info = {};
13558 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
13559 memory_info.allocationSize = 0;
13560 memory_info.memoryTypeIndex = 0;
13562 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
13563 memory_info.allocationSize = memory_reqs.size;
13564 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
13567 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
13568 ASSERT_VK_SUCCESS(err);
13569 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
13570 ASSERT_VK_SUCCESS(err);
13573 VkBufferViewCreateInfo bvci = {};
13574 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
13575 bvci.buffer = buffer;
13576 bvci.format = VK_FORMAT_R8_UNORM;
13577 bvci.range = VK_WHOLE_SIZE;
13579 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
13580 ASSERT_VK_SUCCESS(err);
13582 VkWriteDescriptorSet descriptor_write = {};
13583 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13584 descriptor_write.dstSet = descriptor_set;
13585 descriptor_write.dstBinding = 0;
13586 descriptor_write.descriptorCount = 1;
13587 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13588 descriptor_write.pTexelBufferView = &view;
13590 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13592 char const *vsSource = "#version 450\n"
13594 "out gl_PerVertex { \n"
13595 " vec4 gl_Position;\n"
13598 " gl_Position = vec4(1);\n"
13600 char const *fsSource = "#version 450\n"
13602 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
13603 "layout(location=0) out vec4 x;\n"
13605 " x = imageLoad(s, 0);\n"
13607 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13608 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13609 VkPipelineObj pipe(m_device);
13610 pipe.AddShader(&vs);
13611 pipe.AddShader(&fs);
13612 pipe.AddColorAttachment();
13613 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13615 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
13617 BeginCommandBuffer();
13618 VkViewport viewport = {0, 0, 16, 16, 0, 1};
13619 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
13620 VkRect2D scissor = {{0, 0}, {16, 16}};
13621 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
13622 // Bind pipeline to cmd buffer
13623 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13624 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13625 &descriptor_set, 0, nullptr);
13627 EndCommandBuffer();
13629 VkSubmitInfo submit_info = {};
13630 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13631 submit_info.commandBufferCount = 1;
13632 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13633 // Submit cmd buffer and then destroy bufferView while in-flight
13634 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13636 vkDestroyBufferView(m_device->device(), view, nullptr);
13637 m_errorMonitor->VerifyFound();
13638 vkQueueWaitIdle(m_device->m_queue);
13639 // Now we can actually destroy bufferView
13640 vkDestroyBufferView(m_device->device(), view, NULL);
13641 vkDestroyBuffer(m_device->device(), buffer, NULL);
13642 vkFreeMemory(m_device->device(), buffer_memory, NULL);
13643 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13644 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13645 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13648 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
13649 TEST_DESCRIPTION("Delete in-use sampler.");
13651 ASSERT_NO_FATAL_FAILURE(InitState());
13652 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13654 VkDescriptorPoolSize ds_type_count;
13655 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13656 ds_type_count.descriptorCount = 1;
13658 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13659 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13660 ds_pool_ci.maxSets = 1;
13661 ds_pool_ci.poolSizeCount = 1;
13662 ds_pool_ci.pPoolSizes = &ds_type_count;
13664 VkDescriptorPool ds_pool;
13665 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13666 ASSERT_VK_SUCCESS(err);
13668 VkSamplerCreateInfo sampler_ci = {};
13669 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13670 sampler_ci.pNext = NULL;
13671 sampler_ci.magFilter = VK_FILTER_NEAREST;
13672 sampler_ci.minFilter = VK_FILTER_NEAREST;
13673 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13674 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13675 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13676 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13677 sampler_ci.mipLodBias = 1.0;
13678 sampler_ci.anisotropyEnable = VK_FALSE;
13679 sampler_ci.maxAnisotropy = 1;
13680 sampler_ci.compareEnable = VK_FALSE;
13681 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13682 sampler_ci.minLod = 1.0;
13683 sampler_ci.maxLod = 1.0;
13684 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13685 sampler_ci.unnormalizedCoordinates = VK_FALSE;
13688 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13689 ASSERT_VK_SUCCESS(err);
13691 VkDescriptorSetLayoutBinding layout_binding;
13692 layout_binding.binding = 0;
13693 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13694 layout_binding.descriptorCount = 1;
13695 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13696 layout_binding.pImmutableSamplers = NULL;
13698 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13699 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13700 ds_layout_ci.bindingCount = 1;
13701 ds_layout_ci.pBindings = &layout_binding;
13702 VkDescriptorSetLayout ds_layout;
13703 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13704 ASSERT_VK_SUCCESS(err);
13706 VkDescriptorSetAllocateInfo alloc_info = {};
13707 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13708 alloc_info.descriptorSetCount = 1;
13709 alloc_info.descriptorPool = ds_pool;
13710 alloc_info.pSetLayouts = &ds_layout;
13711 VkDescriptorSet descriptor_set;
13712 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13713 ASSERT_VK_SUCCESS(err);
13715 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13716 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13717 pipeline_layout_ci.pNext = NULL;
13718 pipeline_layout_ci.setLayoutCount = 1;
13719 pipeline_layout_ci.pSetLayouts = &ds_layout;
13721 VkPipelineLayout pipeline_layout;
13722 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13723 ASSERT_VK_SUCCESS(err);
13725 VkImageObj image(m_device);
13726 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13727 ASSERT_TRUE(image.initialized());
13730 VkImageViewCreateInfo ivci = {};
13731 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13732 ivci.image = image.handle();
13733 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13734 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13735 ivci.subresourceRange.layerCount = 1;
13736 ivci.subresourceRange.baseMipLevel = 0;
13737 ivci.subresourceRange.levelCount = 1;
13738 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13740 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13741 ASSERT_VK_SUCCESS(err);
13743 VkDescriptorImageInfo image_info{};
13744 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13745 image_info.imageView = view;
13746 image_info.sampler = sampler;
13748 VkWriteDescriptorSet descriptor_write = {};
13749 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13750 descriptor_write.dstSet = descriptor_set;
13751 descriptor_write.dstBinding = 0;
13752 descriptor_write.descriptorCount = 1;
13753 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13754 descriptor_write.pImageInfo = &image_info;
13756 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13758 // Create PSO to use the sampler
13759 char const *vsSource = "#version 450\n"
13761 "out gl_PerVertex { \n"
13762 " vec4 gl_Position;\n"
13765 " gl_Position = vec4(1);\n"
13767 char const *fsSource = "#version 450\n"
13769 "layout(set=0, binding=0) uniform sampler2D s;\n"
13770 "layout(location=0) out vec4 x;\n"
13772 " x = texture(s, vec2(1));\n"
13774 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13775 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13776 VkPipelineObj pipe(m_device);
13777 pipe.AddShader(&vs);
13778 pipe.AddShader(&fs);
13779 pipe.AddColorAttachment();
13780 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13782 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x");
13784 BeginCommandBuffer();
13785 // Bind pipeline to cmd buffer
13786 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13787 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13788 &descriptor_set, 0, nullptr);
13790 EndCommandBuffer();
13791 // Submit cmd buffer then destroy sampler
13792 VkSubmitInfo submit_info = {};
13793 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13794 submit_info.commandBufferCount = 1;
13795 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13796 // Submit cmd buffer and then destroy sampler while in-flight
13797 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13799 vkDestroySampler(m_device->device(), sampler, nullptr);
13800 m_errorMonitor->VerifyFound();
13801 vkQueueWaitIdle(m_device->m_queue);
13802 // Now we can actually destroy sampler
13803 vkDestroySampler(m_device->device(), sampler, nullptr);
13804 vkDestroyImageView(m_device->device(), view, NULL);
13805 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13806 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13807 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13810 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
13811 TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already "
13812 "signaled but not waited on by the queue. Wait on a "
13813 "fence that has not yet been submitted to a queue.");
13815 ASSERT_NO_FATAL_FAILURE(InitState());
13816 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13818 const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
13819 const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during "
13820 "acquire next image.";
13822 BeginCommandBuffer();
13823 EndCommandBuffer();
13825 VkSemaphoreCreateInfo semaphore_create_info = {};
13826 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13827 VkSemaphore semaphore;
13828 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13829 VkSubmitInfo submit_info = {};
13830 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13831 submit_info.commandBufferCount = 1;
13832 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13833 submit_info.signalSemaphoreCount = 1;
13834 submit_info.pSignalSemaphores = &semaphore;
13835 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13836 m_errorMonitor->SetDesiredFailureMsg(0, "");
13837 vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13838 BeginCommandBuffer();
13839 EndCommandBuffer();
13840 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
13841 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13842 m_errorMonitor->VerifyFound();
13844 VkFenceCreateInfo fence_create_info = {};
13845 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13847 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13849 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
13850 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
13851 m_errorMonitor->VerifyFound();
13853 vkDeviceWaitIdle(m_device->device());
13854 vkDestroyFence(m_device->device(), fence, nullptr);
13855 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13858 TEST_F(VkLayerTest, FramebufferIncompatible) {
13859 TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
13860 "that does not match the framebuffer for the active "
13862 ASSERT_NO_FATAL_FAILURE(InitState());
13863 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13865 // A renderpass with one color attachment.
13866 VkAttachmentDescription attachment = {0,
13867 VK_FORMAT_B8G8R8A8_UNORM,
13868 VK_SAMPLE_COUNT_1_BIT,
13869 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13870 VK_ATTACHMENT_STORE_OP_STORE,
13871 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13872 VK_ATTACHMENT_STORE_OP_DONT_CARE,
13873 VK_IMAGE_LAYOUT_UNDEFINED,
13874 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13876 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13878 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
13880 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
13883 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
13884 ASSERT_VK_SUCCESS(err);
13886 // A compatible framebuffer.
13887 VkImageObj image(m_device);
13888 image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13889 ASSERT_TRUE(image.initialized());
13891 VkImageViewCreateInfo ivci = {
13892 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
13896 VK_IMAGE_VIEW_TYPE_2D,
13897 VK_FORMAT_B8G8R8A8_UNORM,
13898 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13899 VK_COMPONENT_SWIZZLE_IDENTITY},
13900 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
13903 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
13904 ASSERT_VK_SUCCESS(err);
13906 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
13908 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
13909 ASSERT_VK_SUCCESS(err);
13911 VkCommandBufferAllocateInfo cbai = {};
13912 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13913 cbai.commandPool = m_commandPool;
13914 cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13915 cbai.commandBufferCount = 1;
13917 VkCommandBuffer sec_cb;
13918 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
13919 ASSERT_VK_SUCCESS(err);
13920 VkCommandBufferBeginInfo cbbi = {};
13921 VkCommandBufferInheritanceInfo cbii = {};
13922 cbii.renderPass = renderPass();
13923 cbii.framebuffer = fb;
13924 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13926 cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13927 cbbi.pInheritanceInfo = &cbii;
13928 vkBeginCommandBuffer(sec_cb, &cbbi);
13929 vkEndCommandBuffer(sec_cb);
13931 VkCommandBufferBeginInfo cbbi2 = {
13932 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
13935 vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
13936 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13938 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13939 " that is not the same as the primaryCB's current active framebuffer ");
13940 vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
13941 m_errorMonitor->VerifyFound();
13943 vkDestroyImageView(m_device->device(), view, NULL);
13944 vkDestroyRenderPass(m_device->device(), rp, NULL);
13945 vkDestroyFramebuffer(m_device->device(), fb, NULL);
13948 TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
13949 TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
13950 "invalid value. If logicOp is not available, attempt to "
13951 "use it and verify that we see the correct error.");
13952 ASSERT_NO_FATAL_FAILURE(InitState());
13953 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13955 auto features = m_device->phy().features();
13956 // Set the expected error depending on whether or not logicOp available
13957 if (VK_FALSE == features.logicOp) {
13958 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not "
13959 "enabled, logicOpEnable must be "
13962 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
13964 // Create a pipeline using logicOp
13967 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13968 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13970 VkPipelineLayout pipeline_layout;
13971 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13972 ASSERT_VK_SUCCESS(err);
13974 VkPipelineViewportStateCreateInfo vp_state_ci = {};
13975 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13976 vp_state_ci.viewportCount = 1;
13977 VkViewport vp = {}; // Just need dummy vp to point to
13978 vp_state_ci.pViewports = &vp;
13979 vp_state_ci.scissorCount = 1;
13980 VkRect2D scissors = {}; // Dummy scissors to point to
13981 vp_state_ci.pScissors = &scissors;
13983 VkPipelineShaderStageCreateInfo shaderStages[2];
13984 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
13986 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13987 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13988 shaderStages[0] = vs.GetStageCreateInfo();
13989 shaderStages[1] = fs.GetStageCreateInfo();
13991 VkPipelineVertexInputStateCreateInfo vi_ci = {};
13992 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13994 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
13995 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13996 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13998 VkPipelineRasterizationStateCreateInfo rs_ci = {};
13999 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14000 rs_ci.lineWidth = 1.0f;
14002 VkPipelineColorBlendAttachmentState att = {};
14003 att.blendEnable = VK_FALSE;
14004 att.colorWriteMask = 0xf;
14006 VkPipelineColorBlendStateCreateInfo cb_ci = {};
14007 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
14008 // Enable logicOp & set logicOp to value 1 beyond allowed entries
14009 cb_ci.logicOpEnable = VK_TRUE;
14010 cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
14011 cb_ci.attachmentCount = 1;
14012 cb_ci.pAttachments = &att;
14014 VkPipelineMultisampleStateCreateInfo ms_ci = {};
14015 ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14016 ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14018 VkGraphicsPipelineCreateInfo gp_ci = {};
14019 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14020 gp_ci.stageCount = 2;
14021 gp_ci.pStages = shaderStages;
14022 gp_ci.pVertexInputState = &vi_ci;
14023 gp_ci.pInputAssemblyState = &ia_ci;
14024 gp_ci.pViewportState = &vp_state_ci;
14025 gp_ci.pRasterizationState = &rs_ci;
14026 gp_ci.pColorBlendState = &cb_ci;
14027 gp_ci.pMultisampleState = &ms_ci;
14028 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14029 gp_ci.layout = pipeline_layout;
14030 gp_ci.renderPass = renderPass();
14032 VkPipelineCacheCreateInfo pc_ci = {};
14033 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14035 VkPipeline pipeline;
14036 VkPipelineCache pipelineCache;
14037 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
14038 ASSERT_VK_SUCCESS(err);
14040 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
14041 m_errorMonitor->VerifyFound();
14042 if (VK_SUCCESS == err) {
14043 vkDestroyPipeline(m_device->device(), pipeline, NULL);
14045 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
14046 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
14048 #endif // DRAW_STATE_TESTS
14050 #if THREADING_TESTS
14051 #if GTEST_IS_THREADSAFE
14052 struct thread_data_struct {
14053 VkCommandBuffer commandBuffer;
14058 extern "C" void *AddToCommandBuffer(void *arg) {
14059 struct thread_data_struct *data = (struct thread_data_struct *)arg;
14061 for (int i = 0; i < 80000; i++) {
14062 vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
14063 if (data->bailout) {
14070 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
14071 test_platform_thread thread;
14073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
14075 ASSERT_NO_FATAL_FAILURE(InitState());
14076 ASSERT_NO_FATAL_FAILURE(InitViewport());
14077 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14079 // Calls AllocateCommandBuffers
14080 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
14082 // Avoid creating RenderPass
14083 commandBuffer.BeginCommandBuffer();
14085 VkEventCreateInfo event_info;
14089 memset(&event_info, 0, sizeof(event_info));
14090 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
14092 err = vkCreateEvent(device(), &event_info, NULL, &event);
14093 ASSERT_VK_SUCCESS(err);
14095 err = vkResetEvent(device(), event);
14096 ASSERT_VK_SUCCESS(err);
14098 struct thread_data_struct data;
14099 data.commandBuffer = commandBuffer.GetBufferHandle();
14100 data.event = event;
14101 data.bailout = false;
14102 m_errorMonitor->SetBailout(&data.bailout);
14104 // First do some correct operations using multiple threads.
14105 // Add many entries to command buffer from another thread.
14106 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14107 // Make non-conflicting calls from this thread at the same time.
14108 for (int i = 0; i < 80000; i++) {
14110 vkEnumeratePhysicalDevices(instance(), &count, NULL);
14112 test_platform_thread_join(thread, NULL);
14114 // Then do some incorrect operations using multiple threads.
14115 // Add many entries to command buffer from another thread.
14116 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14117 // Add many entries to command buffer from this thread at the same time.
14118 AddToCommandBuffer(&data);
14120 test_platform_thread_join(thread, NULL);
14121 commandBuffer.EndCommandBuffer();
14123 m_errorMonitor->SetBailout(NULL);
14125 m_errorMonitor->VerifyFound();
14127 vkDestroyEvent(device(), event, NULL);
14129 #endif // GTEST_IS_THREADSAFE
14130 #endif // THREADING_TESTS
14132 #if SHADER_CHECKER_TESTS
14133 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
14134 TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14135 "with an impossible code size");
14137 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
14139 ASSERT_NO_FATAL_FAILURE(InitState());
14140 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14142 VkShaderModule module;
14143 VkShaderModuleCreateInfo moduleCreateInfo;
14144 struct icd_spv_header spv;
14146 spv.magic = ICD_SPV_MAGIC;
14147 spv.version = ICD_SPV_VERSION;
14150 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14151 moduleCreateInfo.pNext = NULL;
14152 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14153 moduleCreateInfo.codeSize = 4;
14154 moduleCreateInfo.flags = 0;
14155 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14157 m_errorMonitor->VerifyFound();
14160 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
14161 TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14162 "with a bad magic number");
14164 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
14166 ASSERT_NO_FATAL_FAILURE(InitState());
14167 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14169 VkShaderModule module;
14170 VkShaderModuleCreateInfo moduleCreateInfo;
14171 struct icd_spv_header spv;
14173 spv.magic = ~ICD_SPV_MAGIC;
14174 spv.version = ICD_SPV_VERSION;
14177 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14178 moduleCreateInfo.pNext = NULL;
14179 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14180 moduleCreateInfo.codeSize = sizeof(spv) + 10;
14181 moduleCreateInfo.flags = 0;
14182 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14184 m_errorMonitor->VerifyFound();
14188 // Not currently covered by SPIRV-Tools validator
14189 TEST_F(VkLayerTest, InvalidSPIRVVersion) {
14190 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14191 "Invalid SPIR-V header");
14193 ASSERT_NO_FATAL_FAILURE(InitState());
14194 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14196 VkShaderModule module;
14197 VkShaderModuleCreateInfo moduleCreateInfo;
14198 struct icd_spv_header spv;
14200 spv.magic = ICD_SPV_MAGIC;
14201 spv.version = ~ICD_SPV_VERSION;
14204 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14205 moduleCreateInfo.pNext = NULL;
14207 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14208 moduleCreateInfo.codeSize = sizeof(spv) + 10;
14209 moduleCreateInfo.flags = 0;
14210 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14212 m_errorMonitor->VerifyFound();
14216 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
14217 TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
14218 "is not consumed by the fragment stage");
14219 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
14221 ASSERT_NO_FATAL_FAILURE(InitState());
14222 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14224 char const *vsSource = "#version 450\n"
14226 "layout(location=0) out float x;\n"
14227 "out gl_PerVertex {\n"
14228 " vec4 gl_Position;\n"
14231 " gl_Position = vec4(1);\n"
14234 char const *fsSource = "#version 450\n"
14236 "layout(location=0) out vec4 color;\n"
14238 " color = vec4(1);\n"
14241 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14242 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14244 VkPipelineObj pipe(m_device);
14245 pipe.AddColorAttachment();
14246 pipe.AddShader(&vs);
14247 pipe.AddShader(&fs);
14249 VkDescriptorSetObj descriptorSet(m_device);
14250 descriptorSet.AppendDummy();
14251 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14253 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14255 m_errorMonitor->VerifyFound();
14258 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
14259 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14260 "which is not present in the outputs of the previous stage");
14262 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14264 ASSERT_NO_FATAL_FAILURE(InitState());
14265 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14267 char const *vsSource = "#version 450\n"
14269 "out gl_PerVertex {\n"
14270 " vec4 gl_Position;\n"
14273 " gl_Position = vec4(1);\n"
14275 char const *fsSource = "#version 450\n"
14277 "layout(location=0) in float x;\n"
14278 "layout(location=0) out vec4 color;\n"
14280 " color = vec4(x);\n"
14283 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14284 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14286 VkPipelineObj pipe(m_device);
14287 pipe.AddColorAttachment();
14288 pipe.AddShader(&vs);
14289 pipe.AddShader(&fs);
14291 VkDescriptorSetObj descriptorSet(m_device);
14292 descriptorSet.AppendDummy();
14293 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14295 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14297 m_errorMonitor->VerifyFound();
14300 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
14301 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14302 "within an interace block, which is not present in the outputs "
14303 "of the previous stage.");
14304 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14306 ASSERT_NO_FATAL_FAILURE(InitState());
14307 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14309 char const *vsSource = "#version 450\n"
14311 "out gl_PerVertex {\n"
14312 " vec4 gl_Position;\n"
14315 " gl_Position = vec4(1);\n"
14317 char const *fsSource = "#version 450\n"
14319 "in block { layout(location=0) float x; } ins;\n"
14320 "layout(location=0) out vec4 color;\n"
14322 " color = vec4(ins.x);\n"
14325 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14326 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14328 VkPipelineObj pipe(m_device);
14329 pipe.AddColorAttachment();
14330 pipe.AddShader(&vs);
14331 pipe.AddShader(&fs);
14333 VkDescriptorSetObj descriptorSet(m_device);
14334 descriptorSet.AppendDummy();
14335 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14337 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14339 m_errorMonitor->VerifyFound();
14342 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
14343 TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
14344 "across the VS->FS interface");
14345 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
14346 "output arr[2] of float32' vs 'ptr to "
14347 "input arr[3] of float32'");
14349 ASSERT_NO_FATAL_FAILURE(InitState());
14350 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14352 char const *vsSource = "#version 450\n"
14354 "layout(location=0) out float x[2];\n"
14355 "out gl_PerVertex {\n"
14356 " vec4 gl_Position;\n"
14359 " x[0] = 0; x[1] = 0;\n"
14360 " gl_Position = vec4(1);\n"
14362 char const *fsSource = "#version 450\n"
14364 "layout(location=0) in float x[3];\n"
14365 "layout(location=0) out vec4 color;\n"
14367 " color = vec4(x[0] + x[1] + x[2]);\n"
14370 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14371 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14373 VkPipelineObj pipe(m_device);
14374 pipe.AddColorAttachment();
14375 pipe.AddShader(&vs);
14376 pipe.AddShader(&fs);
14378 VkDescriptorSetObj descriptorSet(m_device);
14379 descriptorSet.AppendDummy();
14380 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14382 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14384 m_errorMonitor->VerifyFound();
14387 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
14388 TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14389 "the VS->FS interface");
14390 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14392 ASSERT_NO_FATAL_FAILURE(InitState());
14393 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14395 char const *vsSource = "#version 450\n"
14397 "layout(location=0) out int x;\n"
14398 "out gl_PerVertex {\n"
14399 " vec4 gl_Position;\n"
14403 " gl_Position = vec4(1);\n"
14405 char const *fsSource = "#version 450\n"
14407 "layout(location=0) in float x;\n" /* VS writes int */
14408 "layout(location=0) out vec4 color;\n"
14410 " color = vec4(x);\n"
14413 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14414 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14416 VkPipelineObj pipe(m_device);
14417 pipe.AddColorAttachment();
14418 pipe.AddShader(&vs);
14419 pipe.AddShader(&fs);
14421 VkDescriptorSetObj descriptorSet(m_device);
14422 descriptorSet.AppendDummy();
14423 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14425 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14427 m_errorMonitor->VerifyFound();
14430 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
14431 TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14432 "the VS->FS interface, when the variable is contained within "
14433 "an interface block");
14434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14436 ASSERT_NO_FATAL_FAILURE(InitState());
14437 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14439 char const *vsSource = "#version 450\n"
14441 "out block { layout(location=0) int x; } outs;\n"
14442 "out gl_PerVertex {\n"
14443 " vec4 gl_Position;\n"
14447 " gl_Position = vec4(1);\n"
14449 char const *fsSource = "#version 450\n"
14451 "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
14452 "layout(location=0) out vec4 color;\n"
14454 " color = vec4(ins.x);\n"
14457 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14458 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14460 VkPipelineObj pipe(m_device);
14461 pipe.AddColorAttachment();
14462 pipe.AddShader(&vs);
14463 pipe.AddShader(&fs);
14465 VkDescriptorSetObj descriptorSet(m_device);
14466 descriptorSet.AppendDummy();
14467 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14469 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14471 m_errorMonitor->VerifyFound();
14474 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
14475 TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
14476 "the VS->FS interface; This should manifest as a not-written/not-consumed "
14477 "pair, but flushes out broken walking of the interfaces");
14478 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
14480 ASSERT_NO_FATAL_FAILURE(InitState());
14481 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14483 char const *vsSource = "#version 450\n"
14485 "out block { layout(location=1) float x; } outs;\n"
14486 "out gl_PerVertex {\n"
14487 " vec4 gl_Position;\n"
14491 " gl_Position = vec4(1);\n"
14493 char const *fsSource = "#version 450\n"
14495 "in block { layout(location=0) float x; } ins;\n"
14496 "layout(location=0) out vec4 color;\n"
14498 " color = vec4(ins.x);\n"
14501 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14502 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14504 VkPipelineObj pipe(m_device);
14505 pipe.AddColorAttachment();
14506 pipe.AddShader(&vs);
14507 pipe.AddShader(&fs);
14509 VkDescriptorSetObj descriptorSet(m_device);
14510 descriptorSet.AppendDummy();
14511 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14513 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14515 m_errorMonitor->VerifyFound();
14518 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
14519 TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
14520 "VS->FS interface. It's not enough to have the same set of locations in "
14521 "use; matching is defined in terms of spirv variables.");
14522 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
14524 ASSERT_NO_FATAL_FAILURE(InitState());
14525 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14527 char const *vsSource = "#version 450\n"
14529 "out block { layout(location=0, component=0) float x; } outs;\n"
14530 "out gl_PerVertex {\n"
14531 " vec4 gl_Position;\n"
14535 " gl_Position = vec4(1);\n"
14537 char const *fsSource = "#version 450\n"
14539 "in block { layout(location=0, component=1) float x; } ins;\n"
14540 "layout(location=0) out vec4 color;\n"
14542 " color = vec4(ins.x);\n"
14545 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14546 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14548 VkPipelineObj pipe(m_device);
14549 pipe.AddColorAttachment();
14550 pipe.AddShader(&vs);
14551 pipe.AddShader(&fs);
14553 VkDescriptorSetObj descriptorSet(m_device);
14554 descriptorSet.AppendDummy();
14555 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14557 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14559 m_errorMonitor->VerifyFound();
14562 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
14563 TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
14564 "not consumed by the vertex shader");
14565 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14567 ASSERT_NO_FATAL_FAILURE(InitState());
14568 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14570 VkVertexInputBindingDescription input_binding;
14571 memset(&input_binding, 0, sizeof(input_binding));
14573 VkVertexInputAttributeDescription input_attrib;
14574 memset(&input_attrib, 0, sizeof(input_attrib));
14575 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14577 char const *vsSource = "#version 450\n"
14579 "out gl_PerVertex {\n"
14580 " vec4 gl_Position;\n"
14583 " gl_Position = vec4(1);\n"
14585 char const *fsSource = "#version 450\n"
14587 "layout(location=0) out vec4 color;\n"
14589 " color = vec4(1);\n"
14592 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14593 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14595 VkPipelineObj pipe(m_device);
14596 pipe.AddColorAttachment();
14597 pipe.AddShader(&vs);
14598 pipe.AddShader(&fs);
14600 pipe.AddVertexInputBindings(&input_binding, 1);
14601 pipe.AddVertexInputAttribs(&input_attrib, 1);
14603 VkDescriptorSetObj descriptorSet(m_device);
14604 descriptorSet.AppendDummy();
14605 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14607 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14609 m_errorMonitor->VerifyFound();
14612 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
14613 TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
14614 "vertex attributes. This flushes out bad behavior in the interface walker");
14615 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14617 ASSERT_NO_FATAL_FAILURE(InitState());
14618 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14620 VkVertexInputBindingDescription input_binding;
14621 memset(&input_binding, 0, sizeof(input_binding));
14623 VkVertexInputAttributeDescription input_attrib;
14624 memset(&input_attrib, 0, sizeof(input_attrib));
14625 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14627 char const *vsSource = "#version 450\n"
14629 "layout(location=1) in float x;\n"
14630 "out gl_PerVertex {\n"
14631 " vec4 gl_Position;\n"
14634 " gl_Position = vec4(x);\n"
14636 char const *fsSource = "#version 450\n"
14638 "layout(location=0) out vec4 color;\n"
14640 " color = vec4(1);\n"
14643 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14644 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14646 VkPipelineObj pipe(m_device);
14647 pipe.AddColorAttachment();
14648 pipe.AddShader(&vs);
14649 pipe.AddShader(&fs);
14651 pipe.AddVertexInputBindings(&input_binding, 1);
14652 pipe.AddVertexInputAttribs(&input_attrib, 1);
14654 VkDescriptorSetObj descriptorSet(m_device);
14655 descriptorSet.AppendDummy();
14656 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14658 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14660 m_errorMonitor->VerifyFound();
14663 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
14664 TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
14665 "provided by a vertex attribute");
14666 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
14668 ASSERT_NO_FATAL_FAILURE(InitState());
14669 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14671 char const *vsSource = "#version 450\n"
14673 "layout(location=0) in vec4 x;\n" /* not provided */
14674 "out gl_PerVertex {\n"
14675 " vec4 gl_Position;\n"
14678 " gl_Position = x;\n"
14680 char const *fsSource = "#version 450\n"
14682 "layout(location=0) out vec4 color;\n"
14684 " color = vec4(1);\n"
14687 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14688 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14690 VkPipelineObj pipe(m_device);
14691 pipe.AddColorAttachment();
14692 pipe.AddShader(&vs);
14693 pipe.AddShader(&fs);
14695 VkDescriptorSetObj descriptorSet(m_device);
14696 descriptorSet.AppendDummy();
14697 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14699 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14701 m_errorMonitor->VerifyFound();
14704 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
14705 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
14706 "fundamental type (float/int/uint) of an attribute and the "
14707 "vertex shader input that consumes it");
14708 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
14710 ASSERT_NO_FATAL_FAILURE(InitState());
14711 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14713 VkVertexInputBindingDescription input_binding;
14714 memset(&input_binding, 0, sizeof(input_binding));
14716 VkVertexInputAttributeDescription input_attrib;
14717 memset(&input_attrib, 0, sizeof(input_attrib));
14718 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14720 char const *vsSource = "#version 450\n"
14722 "layout(location=0) in int x;\n" /* attrib provided float */
14723 "out gl_PerVertex {\n"
14724 " vec4 gl_Position;\n"
14727 " gl_Position = vec4(x);\n"
14729 char const *fsSource = "#version 450\n"
14731 "layout(location=0) out vec4 color;\n"
14733 " color = vec4(1);\n"
14736 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14737 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14739 VkPipelineObj pipe(m_device);
14740 pipe.AddColorAttachment();
14741 pipe.AddShader(&vs);
14742 pipe.AddShader(&fs);
14744 pipe.AddVertexInputBindings(&input_binding, 1);
14745 pipe.AddVertexInputAttribs(&input_attrib, 1);
14747 VkDescriptorSetObj descriptorSet(m_device);
14748 descriptorSet.AppendDummy();
14749 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14751 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14753 m_errorMonitor->VerifyFound();
14756 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
14757 TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
14758 "shaders for the same stage");
14759 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14760 "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
14762 ASSERT_NO_FATAL_FAILURE(InitState());
14763 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14765 char const *vsSource = "#version 450\n"
14767 "out gl_PerVertex {\n"
14768 " vec4 gl_Position;\n"
14771 " gl_Position = vec4(1);\n"
14773 char const *fsSource = "#version 450\n"
14775 "layout(location=0) out vec4 color;\n"
14777 " color = vec4(1);\n"
14780 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14781 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14783 VkPipelineObj pipe(m_device);
14784 pipe.AddColorAttachment();
14785 pipe.AddShader(&vs);
14786 pipe.AddShader(&vs);
14787 pipe.AddShader(&fs);
14789 VkDescriptorSetObj descriptorSet(m_device);
14790 descriptorSet.AppendDummy();
14791 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14793 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14795 m_errorMonitor->VerifyFound();
14798 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
14799 TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
14800 "as vertex attributes");
14801 m_errorMonitor->ExpectSuccess();
14803 ASSERT_NO_FATAL_FAILURE(InitState());
14804 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14806 VkVertexInputBindingDescription input_binding;
14807 memset(&input_binding, 0, sizeof(input_binding));
14809 VkVertexInputAttributeDescription input_attribs[2];
14810 memset(input_attribs, 0, sizeof(input_attribs));
14812 for (int i = 0; i < 2; i++) {
14813 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14814 input_attribs[i].location = i;
14817 char const *vsSource = "#version 450\n"
14819 "layout(location=0) in mat2x4 x;\n"
14820 "out gl_PerVertex {\n"
14821 " vec4 gl_Position;\n"
14824 " gl_Position = x[0] + x[1];\n"
14826 char const *fsSource = "#version 450\n"
14828 "layout(location=0) out vec4 color;\n"
14830 " color = vec4(1);\n"
14833 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14834 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14836 VkPipelineObj pipe(m_device);
14837 pipe.AddColorAttachment();
14838 pipe.AddShader(&vs);
14839 pipe.AddShader(&fs);
14841 pipe.AddVertexInputBindings(&input_binding, 1);
14842 pipe.AddVertexInputAttribs(input_attribs, 2);
14844 VkDescriptorSetObj descriptorSet(m_device);
14845 descriptorSet.AppendDummy();
14846 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14848 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14850 /* expect success */
14851 m_errorMonitor->VerifyNotFound();
14854 TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
14855 m_errorMonitor->ExpectSuccess();
14857 ASSERT_NO_FATAL_FAILURE(InitState());
14858 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14860 VkVertexInputBindingDescription input_binding;
14861 memset(&input_binding, 0, sizeof(input_binding));
14863 VkVertexInputAttributeDescription input_attribs[2];
14864 memset(input_attribs, 0, sizeof(input_attribs));
14866 for (int i = 0; i < 2; i++) {
14867 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14868 input_attribs[i].location = i;
14871 char const *vsSource = "#version 450\n"
14873 "layout(location=0) in vec4 x[2];\n"
14874 "out gl_PerVertex {\n"
14875 " vec4 gl_Position;\n"
14878 " gl_Position = x[0] + x[1];\n"
14880 char const *fsSource = "#version 450\n"
14882 "layout(location=0) out vec4 color;\n"
14884 " color = vec4(1);\n"
14887 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14888 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14890 VkPipelineObj pipe(m_device);
14891 pipe.AddColorAttachment();
14892 pipe.AddShader(&vs);
14893 pipe.AddShader(&fs);
14895 pipe.AddVertexInputBindings(&input_binding, 1);
14896 pipe.AddVertexInputAttribs(input_attribs, 2);
14898 VkDescriptorSetObj descriptorSet(m_device);
14899 descriptorSet.AppendDummy();
14900 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14902 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14904 m_errorMonitor->VerifyNotFound();
14907 TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
14908 TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
14909 "through multiple vertex shader inputs, each consuming a different "
14910 "subset of the components.");
14911 m_errorMonitor->ExpectSuccess();
14913 ASSERT_NO_FATAL_FAILURE(InitState());
14914 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14916 VkVertexInputBindingDescription input_binding;
14917 memset(&input_binding, 0, sizeof(input_binding));
14919 VkVertexInputAttributeDescription input_attribs[3];
14920 memset(input_attribs, 0, sizeof(input_attribs));
14922 for (int i = 0; i < 3; i++) {
14923 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14924 input_attribs[i].location = i;
14927 char const *vsSource = "#version 450\n"
14929 "layout(location=0) in vec4 x;\n"
14930 "layout(location=1) in vec3 y1;\n"
14931 "layout(location=1, component=3) in float y2;\n"
14932 "layout(location=2) in vec4 z;\n"
14933 "out gl_PerVertex {\n"
14934 " vec4 gl_Position;\n"
14937 " gl_Position = x + vec4(y1, y2) + z;\n"
14939 char const *fsSource = "#version 450\n"
14941 "layout(location=0) out vec4 color;\n"
14943 " color = vec4(1);\n"
14946 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14947 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14949 VkPipelineObj pipe(m_device);
14950 pipe.AddColorAttachment();
14951 pipe.AddShader(&vs);
14952 pipe.AddShader(&fs);
14954 pipe.AddVertexInputBindings(&input_binding, 1);
14955 pipe.AddVertexInputAttribs(input_attribs, 3);
14957 VkDescriptorSetObj descriptorSet(m_device);
14958 descriptorSet.AppendDummy();
14959 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14961 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14963 m_errorMonitor->VerifyNotFound();
14966 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
14967 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14968 "No entrypoint found named `foo`");
14970 ASSERT_NO_FATAL_FAILURE(InitState());
14971 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14973 char const *vsSource = "#version 450\n"
14974 "out gl_PerVertex {\n"
14975 " vec4 gl_Position;\n"
14978 " gl_Position = vec4(0);\n"
14980 char const *fsSource = "#version 450\n"
14982 "layout(location=0) out vec4 color;\n"
14984 " color = vec4(1);\n"
14987 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14988 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
14990 VkPipelineObj pipe(m_device);
14991 pipe.AddColorAttachment();
14992 pipe.AddShader(&vs);
14993 pipe.AddShader(&fs);
14995 VkDescriptorSetObj descriptorSet(m_device);
14996 descriptorSet.AppendDummy();
14997 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14999 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15001 m_errorMonitor->VerifyFound();
15004 TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
15005 m_errorMonitor->ExpectSuccess();
15007 ASSERT_NO_FATAL_FAILURE(InitState());
15008 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15010 char const *vsSource = "#version 450\n"
15011 "out gl_PerVertex {\n"
15012 " vec4 gl_Position;\n"
15015 " gl_Position = vec4(0);\n"
15017 char const *fsSource = "#version 450\n"
15019 "layout(location=0) out vec4 color;\n"
15021 " color = vec4(1);\n"
15024 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15025 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15027 VkPipelineObj pipe(m_device);
15028 pipe.AddColorAttachment();
15029 pipe.AddShader(&vs);
15030 pipe.AddShader(&fs);
15032 VkDescriptorSetObj descriptorSet(m_device);
15033 descriptorSet.AppendDummy();
15034 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15036 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15038 m_errorMonitor->VerifyNotFound();
15041 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
15042 m_errorMonitor->SetDesiredFailureMsg(
15043 VK_DEBUG_REPORT_ERROR_BIT_EXT,
15044 "pDepthStencilState is NULL when rasterization is enabled and subpass "
15045 "uses a depth/stencil attachment");
15047 ASSERT_NO_FATAL_FAILURE(InitState());
15048 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15050 char const *vsSource = "#version 450\n"
15051 "void main(){ gl_Position = vec4(0); }\n";
15052 char const *fsSource = "#version 450\n"
15054 "layout(location=0) out vec4 color;\n"
15056 " color = vec4(1);\n"
15059 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15060 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15062 VkPipelineObj pipe(m_device);
15063 pipe.AddColorAttachment();
15064 pipe.AddShader(&vs);
15065 pipe.AddShader(&fs);
15067 VkDescriptorSetObj descriptorSet(m_device);
15068 descriptorSet.AppendDummy();
15069 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15071 VkAttachmentDescription attachments[] = {
15072 { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
15073 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15074 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15075 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15077 { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT,
15078 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15079 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15080 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
15083 VkAttachmentReference refs[] = {
15084 { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
15085 { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL },
15087 VkSubpassDescription subpass = {
15088 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
15089 1, &refs[0], nullptr, &refs[1],
15092 VkRenderPassCreateInfo rpci = {
15093 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
15094 0, 2, attachments, 1, &subpass, 0, nullptr
15097 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15098 ASSERT_VK_SUCCESS(err);
15100 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
15102 m_errorMonitor->VerifyFound();
15104 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15107 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
15108 TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
15109 "set out in 14.1.3: fundamental type must match, and producer side must "
15110 "have at least as many components");
15111 m_errorMonitor->ExpectSuccess();
15113 // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
15115 ASSERT_NO_FATAL_FAILURE(InitState());
15116 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15118 char const *vsSource = "#version 450\n"
15119 "out gl_PerVertex {\n"
15120 " vec4 gl_Position;\n"
15122 "layout(location=0) out vec3 x;\n"
15123 "layout(location=1) out ivec3 y;\n"
15124 "layout(location=2) out vec3 z;\n"
15126 " gl_Position = vec4(0);\n"
15127 " x = vec3(0); y = ivec3(0); z = vec3(0);\n"
15129 char const *fsSource = "#version 450\n"
15131 "layout(location=0) out vec4 color;\n"
15132 "layout(location=0) in float x;\n"
15133 "layout(location=1) flat in int y;\n"
15134 "layout(location=2) in vec2 z;\n"
15136 " color = vec4(1 + x + y + z.x);\n"
15139 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15140 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15142 VkPipelineObj pipe(m_device);
15143 pipe.AddColorAttachment();
15144 pipe.AddShader(&vs);
15145 pipe.AddShader(&fs);
15147 VkDescriptorSetObj descriptorSet(m_device);
15148 descriptorSet.AppendDummy();
15149 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15151 VkResult err = VK_SUCCESS;
15152 err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15153 ASSERT_VK_SUCCESS(err);
15155 m_errorMonitor->VerifyNotFound();
15158 TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
15159 TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
15160 "passed between the TCS and TES stages");
15161 m_errorMonitor->ExpectSuccess();
15163 ASSERT_NO_FATAL_FAILURE(InitState());
15164 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15166 if (!m_device->phy().features().tessellationShader) {
15167 printf("Device does not support tessellation shaders; skipped.\n");
15171 char const *vsSource = "#version 450\n"
15173 char const *tcsSource = "#version 450\n"
15174 "layout(location=0) out int x[];\n"
15175 "layout(vertices=3) out;\n"
15177 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15178 " gl_TessLevelInner[0] = 1;\n"
15179 " x[gl_InvocationID] = gl_InvocationID;\n"
15181 char const *tesSource = "#version 450\n"
15182 "layout(triangles, equal_spacing, cw) in;\n"
15183 "layout(location=0) in int x[];\n"
15184 "out gl_PerVertex { vec4 gl_Position; };\n"
15186 " gl_Position.xyz = gl_TessCoord;\n"
15187 " gl_Position.w = x[0] + x[1] + x[2];\n"
15189 char const *fsSource = "#version 450\n"
15190 "layout(location=0) out vec4 color;\n"
15192 " color = vec4(1);\n"
15195 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15196 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15197 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15198 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15200 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15201 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15203 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15205 VkPipelineObj pipe(m_device);
15206 pipe.SetInputAssembly(&iasci);
15207 pipe.SetTessellation(&tsci);
15208 pipe.AddColorAttachment();
15209 pipe.AddShader(&vs);
15210 pipe.AddShader(&tcs);
15211 pipe.AddShader(&tes);
15212 pipe.AddShader(&fs);
15214 VkDescriptorSetObj descriptorSet(m_device);
15215 descriptorSet.AppendDummy();
15216 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15218 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15220 m_errorMonitor->VerifyNotFound();
15223 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
15224 TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
15225 "interface block passed into the geometry shader. This "
15226 "is interesting because the 'extra' array level is not "
15227 "present on the member type, but on the block instance.");
15228 m_errorMonitor->ExpectSuccess();
15230 ASSERT_NO_FATAL_FAILURE(InitState());
15231 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15233 if (!m_device->phy().features().geometryShader) {
15234 printf("Device does not support geometry shaders; skipped.\n");
15238 char const *vsSource = "#version 450\n"
15239 "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
15241 " vs_out.x = vec4(1);\n"
15243 char const *gsSource = "#version 450\n"
15244 "layout(triangles) in;\n"
15245 "layout(triangle_strip, max_vertices=3) out;\n"
15246 "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
15247 "out gl_PerVertex { vec4 gl_Position; };\n"
15249 " gl_Position = gs_in[0].x;\n"
15252 char const *fsSource = "#version 450\n"
15253 "layout(location=0) out vec4 color;\n"
15255 " color = vec4(1);\n"
15258 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15259 VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
15260 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15262 VkPipelineObj pipe(m_device);
15263 pipe.AddColorAttachment();
15264 pipe.AddShader(&vs);
15265 pipe.AddShader(&gs);
15266 pipe.AddShader(&fs);
15268 VkDescriptorSetObj descriptorSet(m_device);
15269 descriptorSet.AppendDummy();
15270 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15272 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15274 m_errorMonitor->VerifyNotFound();
15277 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
15278 TEST_DESCRIPTION("Test that an error is produced for a variable output from "
15279 "the TCS without the patch decoration, but consumed in the TES "
15280 "with the decoration.");
15281 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage "
15282 "but per-patch in tessellation evaluation shader stage");
15284 ASSERT_NO_FATAL_FAILURE(InitState());
15285 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15287 if (!m_device->phy().features().tessellationShader) {
15288 printf("Device does not support tessellation shaders; skipped.\n");
15292 char const *vsSource = "#version 450\n"
15294 char const *tcsSource = "#version 450\n"
15295 "layout(location=0) out int x[];\n"
15296 "layout(vertices=3) out;\n"
15298 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15299 " gl_TessLevelInner[0] = 1;\n"
15300 " x[gl_InvocationID] = gl_InvocationID;\n"
15302 char const *tesSource = "#version 450\n"
15303 "layout(triangles, equal_spacing, cw) in;\n"
15304 "layout(location=0) patch in int x;\n"
15305 "out gl_PerVertex { vec4 gl_Position; };\n"
15307 " gl_Position.xyz = gl_TessCoord;\n"
15308 " gl_Position.w = x;\n"
15310 char const *fsSource = "#version 450\n"
15311 "layout(location=0) out vec4 color;\n"
15313 " color = vec4(1);\n"
15316 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15317 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15318 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15319 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15321 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15322 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15324 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15326 VkPipelineObj pipe(m_device);
15327 pipe.SetInputAssembly(&iasci);
15328 pipe.SetTessellation(&tsci);
15329 pipe.AddColorAttachment();
15330 pipe.AddShader(&vs);
15331 pipe.AddShader(&tcs);
15332 pipe.AddShader(&tes);
15333 pipe.AddShader(&fs);
15335 VkDescriptorSetObj descriptorSet(m_device);
15336 descriptorSet.AppendDummy();
15337 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15339 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15341 m_errorMonitor->VerifyFound();
15344 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
15345 TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
15346 "bindings provide the same location");
15347 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15348 "Duplicate vertex input binding descriptions for binding 0");
15350 ASSERT_NO_FATAL_FAILURE(InitState());
15351 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15353 /* Two binding descriptions for binding 0 */
15354 VkVertexInputBindingDescription input_bindings[2];
15355 memset(input_bindings, 0, sizeof(input_bindings));
15357 VkVertexInputAttributeDescription input_attrib;
15358 memset(&input_attrib, 0, sizeof(input_attrib));
15359 input_attrib.format = VK_FORMAT_R32_SFLOAT;
15361 char const *vsSource = "#version 450\n"
15363 "layout(location=0) in float x;\n" /* attrib provided float */
15364 "out gl_PerVertex {\n"
15365 " vec4 gl_Position;\n"
15368 " gl_Position = vec4(x);\n"
15370 char const *fsSource = "#version 450\n"
15372 "layout(location=0) out vec4 color;\n"
15374 " color = vec4(1);\n"
15377 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15378 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15380 VkPipelineObj pipe(m_device);
15381 pipe.AddColorAttachment();
15382 pipe.AddShader(&vs);
15383 pipe.AddShader(&fs);
15385 pipe.AddVertexInputBindings(input_bindings, 2);
15386 pipe.AddVertexInputAttribs(&input_attrib, 1);
15388 VkDescriptorSetObj descriptorSet(m_device);
15389 descriptorSet.AppendDummy();
15390 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15392 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15394 m_errorMonitor->VerifyFound();
15397 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
15398 TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
15399 "attributes. This is interesting because they consume multiple "
15401 m_errorMonitor->ExpectSuccess();
15403 ASSERT_NO_FATAL_FAILURE(InitState());
15404 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15406 if (!m_device->phy().features().shaderFloat64) {
15407 printf("Device does not support 64bit vertex attributes; skipped.\n");
15411 VkVertexInputBindingDescription input_bindings[1];
15412 memset(input_bindings, 0, sizeof(input_bindings));
15414 VkVertexInputAttributeDescription input_attribs[4];
15415 memset(input_attribs, 0, sizeof(input_attribs));
15416 input_attribs[0].location = 0;
15417 input_attribs[0].offset = 0;
15418 input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15419 input_attribs[1].location = 2;
15420 input_attribs[1].offset = 32;
15421 input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15422 input_attribs[2].location = 4;
15423 input_attribs[2].offset = 64;
15424 input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15425 input_attribs[3].location = 6;
15426 input_attribs[3].offset = 96;
15427 input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15429 char const *vsSource = "#version 450\n"
15431 "layout(location=0) in dmat4 x;\n"
15432 "out gl_PerVertex {\n"
15433 " vec4 gl_Position;\n"
15436 " gl_Position = vec4(x[0][0]);\n"
15438 char const *fsSource = "#version 450\n"
15440 "layout(location=0) out vec4 color;\n"
15442 " color = vec4(1);\n"
15445 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15446 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15448 VkPipelineObj pipe(m_device);
15449 pipe.AddColorAttachment();
15450 pipe.AddShader(&vs);
15451 pipe.AddShader(&fs);
15453 pipe.AddVertexInputBindings(input_bindings, 1);
15454 pipe.AddVertexInputAttribs(input_attribs, 4);
15456 VkDescriptorSetObj descriptorSet(m_device);
15457 descriptorSet.AppendDummy();
15458 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15460 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15462 m_errorMonitor->VerifyNotFound();
15465 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
15466 TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
15467 "provide an output for one of the pipeline's color attachments");
15468 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
15470 ASSERT_NO_FATAL_FAILURE(InitState());
15472 char const *vsSource = "#version 450\n"
15474 "out gl_PerVertex {\n"
15475 " vec4 gl_Position;\n"
15478 " gl_Position = vec4(1);\n"
15480 char const *fsSource = "#version 450\n"
15485 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15486 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15488 VkPipelineObj pipe(m_device);
15489 pipe.AddShader(&vs);
15490 pipe.AddShader(&fs);
15492 /* set up CB 0, not written */
15493 pipe.AddColorAttachment();
15494 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15496 VkDescriptorSetObj descriptorSet(m_device);
15497 descriptorSet.AppendDummy();
15498 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15500 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15502 m_errorMonitor->VerifyFound();
15505 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
15506 TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
15507 "output with no matching attachment");
15508 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
15509 "FS writes to output location 1 with no matching attachment");
15511 ASSERT_NO_FATAL_FAILURE(InitState());
15513 char const *vsSource = "#version 450\n"
15515 "out gl_PerVertex {\n"
15516 " vec4 gl_Position;\n"
15519 " gl_Position = vec4(1);\n"
15521 char const *fsSource = "#version 450\n"
15523 "layout(location=0) out vec4 x;\n"
15524 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
15530 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15531 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15533 VkPipelineObj pipe(m_device);
15534 pipe.AddShader(&vs);
15535 pipe.AddShader(&fs);
15537 /* set up CB 0, not written */
15538 pipe.AddColorAttachment();
15539 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15540 /* FS writes CB 1, but we don't configure it */
15542 VkDescriptorSetObj descriptorSet(m_device);
15543 descriptorSet.AppendDummy();
15544 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15546 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15548 m_errorMonitor->VerifyFound();
15551 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
15552 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
15553 "type of an FS output variable, and the format of the corresponding attachment");
15554 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
15556 ASSERT_NO_FATAL_FAILURE(InitState());
15558 char const *vsSource = "#version 450\n"
15560 "out gl_PerVertex {\n"
15561 " vec4 gl_Position;\n"
15564 " gl_Position = vec4(1);\n"
15566 char const *fsSource = "#version 450\n"
15568 "layout(location=0) out ivec4 x;\n" /* not UNORM */
15573 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15574 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15576 VkPipelineObj pipe(m_device);
15577 pipe.AddShader(&vs);
15578 pipe.AddShader(&fs);
15580 /* set up CB 0; type is UNORM by default */
15581 pipe.AddColorAttachment();
15582 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15584 VkDescriptorSetObj descriptorSet(m_device);
15585 descriptorSet.AppendDummy();
15586 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15588 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15590 m_errorMonitor->VerifyFound();
15593 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
15594 TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
15595 "block which has no corresponding binding in the pipeline layout");
15596 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
15598 ASSERT_NO_FATAL_FAILURE(InitState());
15600 char const *vsSource = "#version 450\n"
15602 "out gl_PerVertex {\n"
15603 " vec4 gl_Position;\n"
15606 " gl_Position = vec4(1);\n"
15608 char const *fsSource = "#version 450\n"
15610 "layout(location=0) out vec4 x;\n"
15611 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
15613 " x = vec4(bar.y);\n"
15616 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15617 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15619 VkPipelineObj pipe(m_device);
15620 pipe.AddShader(&vs);
15621 pipe.AddShader(&fs);
15623 /* set up CB 0; type is UNORM by default */
15624 pipe.AddColorAttachment();
15625 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15627 VkDescriptorSetObj descriptorSet(m_device);
15628 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15630 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15632 m_errorMonitor->VerifyFound();
15635 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
15636 TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
15637 "which are not provided in the pipeline layout");
15638 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
15640 ASSERT_NO_FATAL_FAILURE(InitState());
15642 char const *vsSource = "#version 450\n"
15644 "layout(push_constant, std430) uniform foo { float x; } consts;\n"
15645 "out gl_PerVertex {\n"
15646 " vec4 gl_Position;\n"
15649 " gl_Position = vec4(consts.x);\n"
15651 char const *fsSource = "#version 450\n"
15653 "layout(location=0) out vec4 x;\n"
15658 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15659 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15661 VkPipelineObj pipe(m_device);
15662 pipe.AddShader(&vs);
15663 pipe.AddShader(&fs);
15665 /* set up CB 0; type is UNORM by default */
15666 pipe.AddColorAttachment();
15667 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15669 VkDescriptorSetObj descriptorSet(m_device);
15670 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15672 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15674 /* should have generated an error -- no push constant ranges provided! */
15675 m_errorMonitor->VerifyFound();
15678 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
15679 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15680 "which is not included in the subpass description");
15681 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15682 "consumes input attachment index 0 but not provided in subpass");
15684 ASSERT_NO_FATAL_FAILURE(InitState());
15686 char const *vsSource = "#version 450\n"
15688 "out gl_PerVertex {\n"
15689 " vec4 gl_Position;\n"
15692 " gl_Position = vec4(1);\n"
15694 char const *fsSource = "#version 450\n"
15696 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15697 "layout(location=0) out vec4 color;\n"
15699 " color = subpassLoad(x);\n"
15702 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15703 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15705 VkPipelineObj pipe(m_device);
15706 pipe.AddShader(&vs);
15707 pipe.AddShader(&fs);
15708 pipe.AddColorAttachment();
15709 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15711 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15712 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15713 VkDescriptorSetLayout dsl;
15714 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15715 ASSERT_VK_SUCCESS(err);
15717 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15718 VkPipelineLayout pl;
15719 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15720 ASSERT_VK_SUCCESS(err);
15723 pipe.CreateVKPipeline(pl, renderPass());
15725 m_errorMonitor->VerifyFound();
15727 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15728 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15731 TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
15732 TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
15733 m_errorMonitor->ExpectSuccess();
15735 ASSERT_NO_FATAL_FAILURE(InitState());
15737 char const *vsSource = "#version 450\n"
15739 "out gl_PerVertex {\n"
15740 " vec4 gl_Position;\n"
15743 " gl_Position = vec4(1);\n"
15745 char const *fsSource = "#version 450\n"
15747 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15748 "layout(location=0) out vec4 color;\n"
15750 " color = subpassLoad(x);\n"
15753 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15754 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15756 VkPipelineObj pipe(m_device);
15757 pipe.AddShader(&vs);
15758 pipe.AddShader(&fs);
15759 pipe.AddColorAttachment();
15760 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15762 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15763 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15764 VkDescriptorSetLayout dsl;
15765 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15766 ASSERT_VK_SUCCESS(err);
15768 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15769 VkPipelineLayout pl;
15770 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15771 ASSERT_VK_SUCCESS(err);
15773 VkAttachmentDescription descs[2] = {
15774 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15775 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15776 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15777 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15778 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15780 VkAttachmentReference color = {
15781 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15783 VkAttachmentReference input = {
15784 1, VK_IMAGE_LAYOUT_GENERAL,
15787 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15789 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15791 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15792 ASSERT_VK_SUCCESS(err);
15794 // should be OK. would go wrong here if it's going to...
15795 pipe.CreateVKPipeline(pl, rp);
15797 m_errorMonitor->VerifyNotFound();
15799 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15800 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15801 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15804 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
15805 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15806 "with a format having a different fundamental type");
15807 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15808 "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
15810 ASSERT_NO_FATAL_FAILURE(InitState());
15812 char const *vsSource = "#version 450\n"
15814 "out gl_PerVertex {\n"
15815 " vec4 gl_Position;\n"
15818 " gl_Position = vec4(1);\n"
15820 char const *fsSource = "#version 450\n"
15822 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15823 "layout(location=0) out vec4 color;\n"
15825 " color = subpassLoad(x);\n"
15828 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15829 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15831 VkPipelineObj pipe(m_device);
15832 pipe.AddShader(&vs);
15833 pipe.AddShader(&fs);
15834 pipe.AddColorAttachment();
15835 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15837 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15838 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15839 VkDescriptorSetLayout dsl;
15840 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15841 ASSERT_VK_SUCCESS(err);
15843 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15844 VkPipelineLayout pl;
15845 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15846 ASSERT_VK_SUCCESS(err);
15848 VkAttachmentDescription descs[2] = {
15849 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15850 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15851 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15852 {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15853 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15855 VkAttachmentReference color = {
15856 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15858 VkAttachmentReference input = {
15859 1, VK_IMAGE_LAYOUT_GENERAL,
15862 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15864 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15866 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15867 ASSERT_VK_SUCCESS(err);
15870 pipe.CreateVKPipeline(pl, rp);
15872 m_errorMonitor->VerifyFound();
15874 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15875 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15876 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15879 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
15880 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15881 "which is not included in the subpass description -- array case");
15882 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15883 "consumes input attachment index 1 but not provided in subpass");
15885 ASSERT_NO_FATAL_FAILURE(InitState());
15887 char const *vsSource = "#version 450\n"
15889 "out gl_PerVertex {\n"
15890 " vec4 gl_Position;\n"
15893 " gl_Position = vec4(1);\n"
15895 char const *fsSource = "#version 450\n"
15897 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n"
15898 "layout(location=0) out vec4 color;\n"
15900 " color = subpassLoad(xs[1]);\n"
15903 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15904 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15906 VkPipelineObj pipe(m_device);
15907 pipe.AddShader(&vs);
15908 pipe.AddShader(&fs);
15909 pipe.AddColorAttachment();
15910 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15912 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15913 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15914 VkDescriptorSetLayout dsl;
15915 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15916 ASSERT_VK_SUCCESS(err);
15918 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15919 VkPipelineLayout pl;
15920 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15921 ASSERT_VK_SUCCESS(err);
15924 pipe.CreateVKPipeline(pl, renderPass());
15926 m_errorMonitor->VerifyFound();
15928 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15929 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15932 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
15933 TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
15934 "descriptor which is not provided in the pipeline layout");
15935 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
15937 ASSERT_NO_FATAL_FAILURE(InitState());
15939 char const *csSource = "#version 450\n"
15941 "layout(local_size_x=1) in;\n"
15942 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15947 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15949 VkDescriptorSetObj descriptorSet(m_device);
15950 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15952 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15955 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15956 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15957 descriptorSet.GetPipelineLayout(),
15962 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
15964 m_errorMonitor->VerifyFound();
15966 if (err == VK_SUCCESS) {
15967 vkDestroyPipeline(m_device->device(), pipe, nullptr);
15971 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
15972 TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
15973 "descriptor-backed resource which is not provided, but the shader does not "
15974 "statically use it. This is interesting because it requires compute pipelines "
15975 "to have a proper descriptor use walk, which they didn't for some time.");
15976 m_errorMonitor->ExpectSuccess();
15978 ASSERT_NO_FATAL_FAILURE(InitState());
15980 char const *csSource = "#version 450\n"
15982 "layout(local_size_x=1) in;\n"
15983 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15985 " // x is not used.\n"
15988 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15990 VkDescriptorSetObj descriptorSet(m_device);
15991 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15993 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15996 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15997 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15998 descriptorSet.GetPipelineLayout(),
16003 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16005 m_errorMonitor->VerifyNotFound();
16007 if (err == VK_SUCCESS) {
16008 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16012 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
16013 TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
16014 "descriptor-backed resource of a mismatched type");
16015 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16016 "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
16018 ASSERT_NO_FATAL_FAILURE(InitState());
16020 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
16021 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding};
16022 VkDescriptorSetLayout dsl;
16023 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16024 ASSERT_VK_SUCCESS(err);
16026 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16027 VkPipelineLayout pl;
16028 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16029 ASSERT_VK_SUCCESS(err);
16031 char const *csSource = "#version 450\n"
16033 "layout(local_size_x=1) in;\n"
16034 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
16038 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16040 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16043 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16044 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16050 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16052 m_errorMonitor->VerifyFound();
16054 if (err == VK_SUCCESS) {
16055 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16058 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16059 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16062 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
16063 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16064 "sampler portion of a combined image + sampler");
16065 m_errorMonitor->ExpectSuccess();
16067 ASSERT_NO_FATAL_FAILURE(InitState());
16069 VkDescriptorSetLayoutBinding bindings[] = {
16070 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16071 {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16072 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16074 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16075 VkDescriptorSetLayout dsl;
16076 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16077 ASSERT_VK_SUCCESS(err);
16079 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16080 VkPipelineLayout pl;
16081 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16082 ASSERT_VK_SUCCESS(err);
16084 char const *csSource = "#version 450\n"
16086 "layout(local_size_x=1) in;\n"
16087 "layout(set=0, binding=0) uniform sampler s;\n"
16088 "layout(set=0, binding=1) uniform texture2D t;\n"
16089 "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16091 " x = texture(sampler2D(t, s), vec2(0));\n"
16093 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16095 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16098 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16099 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16105 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16107 m_errorMonitor->VerifyNotFound();
16109 if (err == VK_SUCCESS) {
16110 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16113 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16114 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16117 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
16118 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16119 "image portion of a combined image + sampler");
16120 m_errorMonitor->ExpectSuccess();
16122 ASSERT_NO_FATAL_FAILURE(InitState());
16124 VkDescriptorSetLayoutBinding bindings[] = {
16125 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16126 {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16127 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16129 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16130 VkDescriptorSetLayout dsl;
16131 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16132 ASSERT_VK_SUCCESS(err);
16134 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16135 VkPipelineLayout pl;
16136 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16137 ASSERT_VK_SUCCESS(err);
16139 char const *csSource = "#version 450\n"
16141 "layout(local_size_x=1) in;\n"
16142 "layout(set=0, binding=0) uniform texture2D t;\n"
16143 "layout(set=0, binding=1) uniform sampler s;\n"
16144 "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16146 " x = texture(sampler2D(t, s), vec2(0));\n"
16148 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16150 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16153 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16154 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16160 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16162 m_errorMonitor->VerifyNotFound();
16164 if (err == VK_SUCCESS) {
16165 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16168 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16169 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16172 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
16173 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
16174 "both the sampler and the image of a combined image+sampler "
16175 "but via separate variables");
16176 m_errorMonitor->ExpectSuccess();
16178 ASSERT_NO_FATAL_FAILURE(InitState());
16180 VkDescriptorSetLayoutBinding bindings[] = {
16181 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16182 {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16184 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
16185 VkDescriptorSetLayout dsl;
16186 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16187 ASSERT_VK_SUCCESS(err);
16189 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16190 VkPipelineLayout pl;
16191 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16192 ASSERT_VK_SUCCESS(err);
16194 char const *csSource = "#version 450\n"
16196 "layout(local_size_x=1) in;\n"
16197 "layout(set=0, binding=0) uniform texture2D t;\n"
16198 "layout(set=0, binding=0) uniform sampler s; // both binding 0!\n"
16199 "layout(set=0, binding=1) buffer block { vec4 x; };\n"
16201 " x = texture(sampler2D(t, s), vec2(0));\n"
16203 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16205 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16208 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16209 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16215 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16217 m_errorMonitor->VerifyNotFound();
16219 if (err == VK_SUCCESS) {
16220 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16223 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16224 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16227 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
16228 TEST_DESCRIPTION("Test that an error is produced when an image view type "
16229 "does not match the dimensionality declared in the shader");
16231 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
16233 ASSERT_NO_FATAL_FAILURE(InitState());
16234 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16236 char const *vsSource = "#version 450\n"
16238 "out gl_PerVertex { vec4 gl_Position; };\n"
16239 "void main() { gl_Position = vec4(0); }\n";
16240 char const *fsSource = "#version 450\n"
16242 "layout(set=0, binding=0) uniform sampler3D s;\n"
16243 "layout(location=0) out vec4 color;\n"
16245 " color = texture(s, vec3(0));\n"
16247 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16248 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16250 VkPipelineObj pipe(m_device);
16251 pipe.AddShader(&vs);
16252 pipe.AddShader(&fs);
16253 pipe.AddColorAttachment();
16255 VkTextureObj texture(m_device, nullptr);
16256 VkSamplerObj sampler(m_device);
16258 VkDescriptorSetObj descriptorSet(m_device);
16259 descriptorSet.AppendSamplerTexture(&sampler, &texture);
16260 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16262 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16263 ASSERT_VK_SUCCESS(err);
16265 BeginCommandBuffer();
16267 m_commandBuffer->BindPipeline(pipe);
16268 m_commandBuffer->BindDescriptorSet(descriptorSet);
16270 VkViewport viewport = {0, 0, 16, 16, 0, 1};
16271 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16272 VkRect2D scissor = {{0, 0}, {16, 16}};
16273 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16275 // error produced here.
16276 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16278 m_errorMonitor->VerifyFound();
16280 EndCommandBuffer();
16283 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
16284 TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
16285 "are consumed via singlesample images types in the shader, or vice versa.");
16287 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
16289 ASSERT_NO_FATAL_FAILURE(InitState());
16290 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16292 char const *vsSource = "#version 450\n"
16294 "out gl_PerVertex { vec4 gl_Position; };\n"
16295 "void main() { gl_Position = vec4(0); }\n";
16296 char const *fsSource = "#version 450\n"
16298 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
16299 "layout(location=0) out vec4 color;\n"
16301 " color = texelFetch(s, ivec2(0), 0);\n"
16303 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16304 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16306 VkPipelineObj pipe(m_device);
16307 pipe.AddShader(&vs);
16308 pipe.AddShader(&fs);
16309 pipe.AddColorAttachment();
16311 VkTextureObj texture(m_device, nullptr);
16312 VkSamplerObj sampler(m_device);
16314 VkDescriptorSetObj descriptorSet(m_device);
16315 descriptorSet.AppendSamplerTexture(&sampler, &texture);
16316 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16318 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16319 ASSERT_VK_SUCCESS(err);
16321 BeginCommandBuffer();
16323 m_commandBuffer->BindPipeline(pipe);
16324 m_commandBuffer->BindDescriptorSet(descriptorSet);
16326 VkViewport viewport = {0, 0, 16, 16, 0, 1};
16327 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16328 VkRect2D scissor = {{0, 0}, {16, 16}};
16329 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16331 // error produced here.
16332 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16334 m_errorMonitor->VerifyFound();
16336 EndCommandBuffer();
16339 #endif // SHADER_CHECKER_TESTS
16341 #if DEVICE_LIMITS_TESTS
16342 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) {
16343 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16345 ASSERT_NO_FATAL_FAILURE(InitState());
16350 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16351 const int32_t tex_width = 32;
16352 const int32_t tex_height = 32;
16354 VkImageCreateInfo image_create_info = {};
16355 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16356 image_create_info.pNext = NULL;
16357 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16358 image_create_info.format = tex_format;
16359 image_create_info.extent.width = tex_width;
16360 image_create_info.extent.height = tex_height;
16361 image_create_info.extent.depth = 1;
16362 image_create_info.mipLevels = 1;
16363 image_create_info.arrayLayers = 1;
16364 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16365 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16366 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16367 image_create_info.flags = 0;
16369 // Introduce error by sending down a bogus width extent
16370 image_create_info.extent.width = 65536;
16371 vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16373 m_errorMonitor->VerifyFound();
16376 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) {
16377 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16378 "CreateImage extents is 0 for at least one required dimension");
16380 ASSERT_NO_FATAL_FAILURE(InitState());
16385 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16386 const int32_t tex_width = 32;
16387 const int32_t tex_height = 32;
16389 VkImageCreateInfo image_create_info = {};
16390 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16391 image_create_info.pNext = NULL;
16392 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16393 image_create_info.format = tex_format;
16394 image_create_info.extent.width = tex_width;
16395 image_create_info.extent.height = tex_height;
16396 image_create_info.extent.depth = 1;
16397 image_create_info.mipLevels = 1;
16398 image_create_info.arrayLayers = 1;
16399 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16400 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16401 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16402 image_create_info.flags = 0;
16404 // Introduce error by sending down a bogus width extent
16405 image_create_info.extent.width = 0;
16406 vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16408 m_errorMonitor->VerifyFound();
16410 #endif // DEVICE_LIMITS_TESTS
16413 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
16414 TEST_DESCRIPTION("Create a render pass with an attachment description "
16415 "format set to VK_FORMAT_UNDEFINED");
16417 ASSERT_NO_FATAL_FAILURE(InitState());
16418 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16420 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
16422 VkAttachmentReference color_attach = {};
16423 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
16424 color_attach.attachment = 0;
16425 VkSubpassDescription subpass = {};
16426 subpass.colorAttachmentCount = 1;
16427 subpass.pColorAttachments = &color_attach;
16429 VkRenderPassCreateInfo rpci = {};
16430 rpci.subpassCount = 1;
16431 rpci.pSubpasses = &subpass;
16432 rpci.attachmentCount = 1;
16433 VkAttachmentDescription attach_desc = {};
16434 attach_desc.format = VK_FORMAT_UNDEFINED;
16435 rpci.pAttachments = &attach_desc;
16436 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16438 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16440 m_errorMonitor->VerifyFound();
16442 if (result == VK_SUCCESS) {
16443 vkDestroyRenderPass(m_device->device(), rp, NULL);
16447 TEST_F(VkLayerTest, InvalidImageView) {
16450 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 ");
16452 ASSERT_NO_FATAL_FAILURE(InitState());
16454 // Create an image and try to create a view with bad baseMipLevel
16457 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16458 const int32_t tex_width = 32;
16459 const int32_t tex_height = 32;
16461 VkImageCreateInfo image_create_info = {};
16462 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16463 image_create_info.pNext = NULL;
16464 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16465 image_create_info.format = tex_format;
16466 image_create_info.extent.width = tex_width;
16467 image_create_info.extent.height = tex_height;
16468 image_create_info.extent.depth = 1;
16469 image_create_info.mipLevels = 1;
16470 image_create_info.arrayLayers = 1;
16471 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16472 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16473 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16474 image_create_info.flags = 0;
16476 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16477 ASSERT_VK_SUCCESS(err);
16479 VkImageViewCreateInfo image_view_create_info = {};
16480 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16481 image_view_create_info.image = image;
16482 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16483 image_view_create_info.format = tex_format;
16484 image_view_create_info.subresourceRange.layerCount = 1;
16485 image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error
16486 image_view_create_info.subresourceRange.levelCount = 1;
16487 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16490 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16492 m_errorMonitor->VerifyFound();
16493 vkDestroyImage(m_device->device(), image, NULL);
16496 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
16498 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16499 " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
16501 ASSERT_NO_FATAL_FAILURE(InitState());
16503 // Create an image and try to create a view with no memory backing the image
16506 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16507 const int32_t tex_width = 32;
16508 const int32_t tex_height = 32;
16510 VkImageCreateInfo image_create_info = {};
16511 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16512 image_create_info.pNext = NULL;
16513 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16514 image_create_info.format = tex_format;
16515 image_create_info.extent.width = tex_width;
16516 image_create_info.extent.height = tex_height;
16517 image_create_info.extent.depth = 1;
16518 image_create_info.mipLevels = 1;
16519 image_create_info.arrayLayers = 1;
16520 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16521 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16522 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16523 image_create_info.flags = 0;
16525 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16526 ASSERT_VK_SUCCESS(err);
16528 VkImageViewCreateInfo image_view_create_info = {};
16529 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16530 image_view_create_info.image = image;
16531 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16532 image_view_create_info.format = tex_format;
16533 image_view_create_info.subresourceRange.layerCount = 1;
16534 image_view_create_info.subresourceRange.baseMipLevel = 0;
16535 image_view_create_info.subresourceRange.levelCount = 1;
16536 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16539 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16541 m_errorMonitor->VerifyFound();
16542 vkDestroyImage(m_device->device(), image, NULL);
16543 // If last error is success, it still created the view, so delete it.
16544 if (err == VK_SUCCESS) {
16545 vkDestroyImageView(m_device->device(), view, NULL);
16549 TEST_F(VkLayerTest, InvalidImageViewAspect) {
16550 TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
16551 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image "
16552 "formats must have ONLY the "
16553 "VK_IMAGE_ASPECT_COLOR_BIT set");
16555 ASSERT_NO_FATAL_FAILURE(InitState());
16557 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16558 VkImageObj image(m_device);
16559 image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
16560 ASSERT_TRUE(image.initialized());
16562 VkImageViewCreateInfo image_view_create_info = {};
16563 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16564 image_view_create_info.image = image.handle();
16565 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16566 image_view_create_info.format = tex_format;
16567 image_view_create_info.subresourceRange.baseMipLevel = 0;
16568 image_view_create_info.subresourceRange.levelCount = 1;
16569 // Cause an error by setting an invalid image aspect
16570 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16573 vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16575 m_errorMonitor->VerifyFound();
16578 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
16582 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16583 "vkCmdCopyImage: number of layers in source and destination subresources for pRegions");
16585 ASSERT_NO_FATAL_FAILURE(InitState());
16587 // Create two images of different types and try to copy between them
16590 VkDeviceMemory srcMem;
16591 VkDeviceMemory destMem;
16592 VkMemoryRequirements memReqs;
16594 VkImageCreateInfo image_create_info = {};
16595 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16596 image_create_info.pNext = NULL;
16597 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16598 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16599 image_create_info.extent.width = 32;
16600 image_create_info.extent.height = 32;
16601 image_create_info.extent.depth = 1;
16602 image_create_info.mipLevels = 1;
16603 image_create_info.arrayLayers = 4;
16604 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16605 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16606 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16607 image_create_info.flags = 0;
16609 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
16610 ASSERT_VK_SUCCESS(err);
16612 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
16613 ASSERT_VK_SUCCESS(err);
16616 VkMemoryAllocateInfo memAlloc = {};
16617 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16618 memAlloc.pNext = NULL;
16619 memAlloc.allocationSize = 0;
16620 memAlloc.memoryTypeIndex = 0;
16622 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
16623 memAlloc.allocationSize = memReqs.size;
16624 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16626 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
16627 ASSERT_VK_SUCCESS(err);
16629 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
16630 memAlloc.allocationSize = memReqs.size;
16631 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16632 ASSERT_VK_SUCCESS(err);
16633 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
16634 ASSERT_VK_SUCCESS(err);
16636 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
16637 ASSERT_VK_SUCCESS(err);
16638 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
16639 ASSERT_VK_SUCCESS(err);
16641 BeginCommandBuffer();
16642 VkImageCopy copyRegion;
16643 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16644 copyRegion.srcSubresource.mipLevel = 0;
16645 copyRegion.srcSubresource.baseArrayLayer = 0;
16646 copyRegion.srcSubresource.layerCount = 1;
16647 copyRegion.srcOffset.x = 0;
16648 copyRegion.srcOffset.y = 0;
16649 copyRegion.srcOffset.z = 0;
16650 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16651 copyRegion.dstSubresource.mipLevel = 0;
16652 copyRegion.dstSubresource.baseArrayLayer = 0;
16653 // Introduce failure by forcing the dst layerCount to differ from src
16654 copyRegion.dstSubresource.layerCount = 3;
16655 copyRegion.dstOffset.x = 0;
16656 copyRegion.dstOffset.y = 0;
16657 copyRegion.dstOffset.z = 0;
16658 copyRegion.extent.width = 1;
16659 copyRegion.extent.height = 1;
16660 copyRegion.extent.depth = 1;
16661 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
16662 EndCommandBuffer();
16664 m_errorMonitor->VerifyFound();
16666 vkDestroyImage(m_device->device(), srcImage, NULL);
16667 vkDestroyImage(m_device->device(), dstImage, NULL);
16668 vkFreeMemory(m_device->device(), srcMem, NULL);
16669 vkFreeMemory(m_device->device(), destMem, NULL);
16672 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
16674 TEST_DESCRIPTION("Creating images with unsuported formats ");
16676 ASSERT_NO_FATAL_FAILURE(InitState());
16677 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16678 VkImageObj image(m_device);
16679 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16680 VK_IMAGE_TILING_OPTIMAL, 0);
16681 ASSERT_TRUE(image.initialized());
16683 // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
16684 VkImageCreateInfo image_create_info;
16685 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16686 image_create_info.pNext = NULL;
16687 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16688 image_create_info.format = VK_FORMAT_UNDEFINED;
16689 image_create_info.extent.width = 32;
16690 image_create_info.extent.height = 32;
16691 image_create_info.extent.depth = 1;
16692 image_create_info.mipLevels = 1;
16693 image_create_info.arrayLayers = 1;
16694 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16695 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16696 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16697 image_create_info.flags = 0;
16699 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16700 "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
16702 VkImage localImage;
16703 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16704 m_errorMonitor->VerifyFound();
16706 VkFormat unsupported = VK_FORMAT_UNDEFINED;
16707 // Look for a format that is COMPLETELY unsupported with this hardware
16708 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
16709 VkFormat format = static_cast<VkFormat>(f);
16710 VkFormatProperties fProps = m_device->format_properties(format);
16711 if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
16712 unsupported = format;
16717 if (unsupported != VK_FORMAT_UNDEFINED) {
16718 image_create_info.format = unsupported;
16719 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
16721 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16722 m_errorMonitor->VerifyFound();
16726 TEST_F(VkLayerTest, ImageLayerViewTests) {
16728 TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
16730 ASSERT_NO_FATAL_FAILURE(InitState());
16732 VkImageObj image(m_device);
16733 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16734 VK_IMAGE_TILING_OPTIMAL, 0);
16735 ASSERT_TRUE(image.initialized());
16737 VkImageView imgView;
16738 VkImageViewCreateInfo imgViewInfo = {};
16739 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16740 imgViewInfo.image = image.handle();
16741 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
16742 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16743 imgViewInfo.subresourceRange.layerCount = 1;
16744 imgViewInfo.subresourceRange.baseMipLevel = 0;
16745 imgViewInfo.subresourceRange.levelCount = 1;
16746 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16748 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel");
16749 // View can't have baseMipLevel >= image's mipLevels - Expect
16750 // VIEW_CREATE_ERROR
16751 imgViewInfo.subresourceRange.baseMipLevel = 1;
16752 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16753 m_errorMonitor->VerifyFound();
16754 imgViewInfo.subresourceRange.baseMipLevel = 0;
16756 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer");
16757 // View can't have baseArrayLayer >= image's arraySize - Expect
16758 // VIEW_CREATE_ERROR
16759 imgViewInfo.subresourceRange.baseArrayLayer = 1;
16760 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16761 m_errorMonitor->VerifyFound();
16762 imgViewInfo.subresourceRange.baseArrayLayer = 0;
16764 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16765 "pCreateInfo->subresourceRange."
16767 // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR
16768 imgViewInfo.subresourceRange.levelCount = 0;
16769 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16770 m_errorMonitor->VerifyFound();
16771 imgViewInfo.subresourceRange.levelCount = 1;
16773 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16774 "pCreateInfo->subresourceRange."
16776 // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR
16777 imgViewInfo.subresourceRange.layerCount = 0;
16778 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16779 m_errorMonitor->VerifyFound();
16780 imgViewInfo.subresourceRange.layerCount = 1;
16782 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats");
16783 // Can't use depth format for view into color image - Expect INVALID_FORMAT
16784 imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
16785 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16786 m_errorMonitor->VerifyFound();
16787 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16789 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless "
16790 "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
16791 "was set on image creation.");
16792 // Same compatibility class but no MUTABLE_FORMAT bit - Expect
16793 // VIEW_CREATE_ERROR
16794 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
16795 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16796 m_errorMonitor->VerifyFound();
16797 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16799 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with "
16800 "differing formats but they must be "
16801 "in the same compatibility class.");
16802 // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect
16803 // VIEW_CREATE_ERROR
16804 VkImageCreateInfo mutImgInfo = image.create_info();
16806 mutImgInfo.format = VK_FORMAT_R8_UINT;
16807 assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
16808 mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
16809 mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
16810 ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage);
16811 ASSERT_VK_SUCCESS(ret);
16812 imgViewInfo.image = mutImage;
16813 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16814 m_errorMonitor->VerifyFound();
16815 imgViewInfo.image = image.handle();
16816 vkDestroyImage(m_device->handle(), mutImage, NULL);
16819 TEST_F(VkLayerTest, MiscImageLayerTests) {
16821 TEST_DESCRIPTION("Image layer tests that don't belong elsewhare");
16823 ASSERT_NO_FATAL_FAILURE(InitState());
16825 VkImageObj image(m_device);
16826 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16827 VK_IMAGE_TILING_OPTIMAL, 0);
16828 ASSERT_TRUE(image.initialized());
16830 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero");
16831 vk_testing::Buffer buffer;
16832 VkMemoryPropertyFlags reqs = 0;
16833 buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
16834 VkBufferImageCopy region = {};
16835 region.bufferRowLength = 128;
16836 region.bufferImageHeight = 128;
16837 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16838 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
16839 region.imageSubresource.layerCount = 0;
16840 region.imageExtent.height = 4;
16841 region.imageExtent.width = 4;
16842 region.imageExtent.depth = 1;
16843 m_commandBuffer->BeginCommandBuffer();
16844 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16845 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16846 m_errorMonitor->VerifyFound();
16847 region.imageSubresource.layerCount = 1;
16849 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
16850 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
16851 region.bufferOffset = 6;
16852 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size");
16853 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16854 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16855 m_errorMonitor->VerifyFound();
16857 // BufferOffset must be a multiple of 4
16858 // Introduce failure by setting bufferOffset to a value not divisible by 4
16859 region.bufferOffset = 6;
16860 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4");
16861 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16862 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16863 m_errorMonitor->VerifyFound();
16865 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
16866 region.bufferOffset = 0;
16867 region.imageExtent.height = 128;
16868 region.imageExtent.width = 128;
16869 // Introduce failure by setting bufferRowLength > 0 but less than width
16870 region.bufferRowLength = 64;
16871 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16872 "must be zero or greater-than-or-equal-to imageExtent.width");
16873 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16874 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16875 m_errorMonitor->VerifyFound();
16877 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
16878 region.bufferRowLength = 128;
16879 // Introduce failure by setting bufferRowHeight > 0 but less than height
16880 region.bufferImageHeight = 64;
16881 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16882 "must be zero or greater-than-or-equal-to imageExtent.height");
16883 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16884 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16885 m_errorMonitor->VerifyFound();
16887 region.bufferImageHeight = 128;
16888 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must "
16889 "specify only COLOR or DEPTH or "
16891 // Expect MISMATCHED_IMAGE_ASPECT
16892 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16893 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16894 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16895 m_errorMonitor->VerifyFound();
16896 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16898 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16899 "If the format of srcImage is a depth, stencil, depth stencil or "
16900 "integer-based format then filter must be VK_FILTER_NEAREST");
16901 // Expect INVALID_FILTER
16902 VkImageObj intImage1(m_device);
16903 intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16904 VkImageObj intImage2(m_device);
16905 intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16906 VkImageBlit blitRegion = {};
16907 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16908 blitRegion.srcSubresource.baseArrayLayer = 0;
16909 blitRegion.srcSubresource.layerCount = 1;
16910 blitRegion.srcSubresource.mipLevel = 0;
16911 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16912 blitRegion.dstSubresource.baseArrayLayer = 0;
16913 blitRegion.dstSubresource.layerCount = 1;
16914 blitRegion.dstSubresource.mipLevel = 0;
16916 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16917 intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR);
16918 m_errorMonitor->VerifyFound();
16920 // Look for NULL-blit warning
16921 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area.");
16922 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16923 intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR);
16924 m_errorMonitor->VerifyFound();
16926 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers");
16927 VkImageMemoryBarrier img_barrier;
16928 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
16929 img_barrier.pNext = NULL;
16930 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
16931 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
16932 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16933 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16934 img_barrier.image = image.handle();
16935 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16936 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16937 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16938 img_barrier.subresourceRange.baseArrayLayer = 0;
16939 img_barrier.subresourceRange.baseMipLevel = 0;
16940 // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE
16941 img_barrier.subresourceRange.layerCount = 0;
16942 img_barrier.subresourceRange.levelCount = 1;
16943 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
16944 nullptr, 0, nullptr, 1, &img_barrier);
16945 m_errorMonitor->VerifyFound();
16946 img_barrier.subresourceRange.layerCount = 1;
16949 TEST_F(VkLayerTest, ImageFormatLimits) {
16951 TEST_DESCRIPTION("Exceed the limits of image format ");
16953 ASSERT_NO_FATAL_FAILURE(InitState());
16954 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16955 VkImageCreateInfo image_create_info = {};
16956 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16957 image_create_info.pNext = NULL;
16958 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16959 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16960 image_create_info.extent.width = 32;
16961 image_create_info.extent.height = 32;
16962 image_create_info.extent.depth = 1;
16963 image_create_info.mipLevels = 1;
16964 image_create_info.arrayLayers = 1;
16965 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16966 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16967 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16968 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
16969 image_create_info.flags = 0;
16972 VkImageFormatProperties imgFmtProps;
16973 vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
16974 image_create_info.usage, image_create_info.flags, &imgFmtProps);
16975 image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1;
16976 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16977 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16978 m_errorMonitor->VerifyFound();
16979 image_create_info.extent.depth = 1;
16981 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16982 image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
16983 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16984 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16985 m_errorMonitor->VerifyFound();
16986 image_create_info.mipLevels = 1;
16988 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16989 image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
16990 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16991 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16992 m_errorMonitor->VerifyFound();
16993 image_create_info.arrayLayers = 1;
16995 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format");
16996 int samples = imgFmtProps.sampleCounts >> 1;
16997 image_create_info.samples = (VkSampleCountFlagBits)samples;
16998 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16999 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17000 m_errorMonitor->VerifyFound();
17001 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17003 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be "
17004 "VK_IMAGE_LAYOUT_UNDEFINED or "
17005 "VK_IMAGE_LAYOUT_PREINITIALIZED");
17006 image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
17007 // Expect INVALID_LAYOUT
17008 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17009 m_errorMonitor->VerifyFound();
17010 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17013 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
17017 // Create color images with different format sizes and try to copy between them
17018 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17019 "vkCmdCopyImage called with unmatched source and dest image format sizes");
17021 ASSERT_NO_FATAL_FAILURE(InitState());
17023 // Create two images of different types and try to copy between them
17026 VkDeviceMemory srcMem;
17027 VkDeviceMemory destMem;
17028 VkMemoryRequirements memReqs;
17030 VkImageCreateInfo image_create_info = {};
17031 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17032 image_create_info.pNext = NULL;
17033 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17034 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17035 image_create_info.extent.width = 32;
17036 image_create_info.extent.height = 32;
17037 image_create_info.extent.depth = 1;
17038 image_create_info.mipLevels = 1;
17039 image_create_info.arrayLayers = 1;
17040 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17041 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17042 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17043 image_create_info.flags = 0;
17045 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17046 ASSERT_VK_SUCCESS(err);
17048 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17049 // Introduce failure by creating second image with a different-sized format.
17050 image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
17052 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17053 ASSERT_VK_SUCCESS(err);
17056 VkMemoryAllocateInfo memAlloc = {};
17057 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17058 memAlloc.pNext = NULL;
17059 memAlloc.allocationSize = 0;
17060 memAlloc.memoryTypeIndex = 0;
17062 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17063 memAlloc.allocationSize = memReqs.size;
17064 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17066 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17067 ASSERT_VK_SUCCESS(err);
17069 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17070 memAlloc.allocationSize = memReqs.size;
17071 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17073 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17074 ASSERT_VK_SUCCESS(err);
17076 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17077 ASSERT_VK_SUCCESS(err);
17078 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17079 ASSERT_VK_SUCCESS(err);
17081 BeginCommandBuffer();
17082 VkImageCopy copyRegion;
17083 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17084 copyRegion.srcSubresource.mipLevel = 0;
17085 copyRegion.srcSubresource.baseArrayLayer = 0;
17086 copyRegion.srcSubresource.layerCount = 0;
17087 copyRegion.srcOffset.x = 0;
17088 copyRegion.srcOffset.y = 0;
17089 copyRegion.srcOffset.z = 0;
17090 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17091 copyRegion.dstSubresource.mipLevel = 0;
17092 copyRegion.dstSubresource.baseArrayLayer = 0;
17093 copyRegion.dstSubresource.layerCount = 0;
17094 copyRegion.dstOffset.x = 0;
17095 copyRegion.dstOffset.y = 0;
17096 copyRegion.dstOffset.z = 0;
17097 copyRegion.extent.width = 1;
17098 copyRegion.extent.height = 1;
17099 copyRegion.extent.depth = 1;
17100 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
17101 EndCommandBuffer();
17103 m_errorMonitor->VerifyFound();
17105 vkDestroyImage(m_device->device(), srcImage, NULL);
17106 vkDestroyImage(m_device->device(), dstImage, NULL);
17107 vkFreeMemory(m_device->device(), srcMem, NULL);
17108 vkFreeMemory(m_device->device(), destMem, NULL);
17111 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
17115 // Create a color image and a depth/stencil image and try to copy between them
17116 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17117 "vkCmdCopyImage called with unmatched source and dest image depth");
17119 ASSERT_NO_FATAL_FAILURE(InitState());
17121 // Create two images of different types and try to copy between them
17124 VkDeviceMemory srcMem;
17125 VkDeviceMemory destMem;
17126 VkMemoryRequirements memReqs;
17128 VkImageCreateInfo image_create_info = {};
17129 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17130 image_create_info.pNext = NULL;
17131 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17132 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17133 image_create_info.extent.width = 32;
17134 image_create_info.extent.height = 32;
17135 image_create_info.extent.depth = 1;
17136 image_create_info.mipLevels = 1;
17137 image_create_info.arrayLayers = 1;
17138 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17139 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17140 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17141 image_create_info.flags = 0;
17143 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17144 ASSERT_VK_SUCCESS(err);
17146 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17148 // Introduce failure by creating second image with a depth/stencil format
17149 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17150 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17151 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17153 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17154 ASSERT_VK_SUCCESS(err);
17157 VkMemoryAllocateInfo memAlloc = {};
17158 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17159 memAlloc.pNext = NULL;
17160 memAlloc.allocationSize = 0;
17161 memAlloc.memoryTypeIndex = 0;
17163 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17164 memAlloc.allocationSize = memReqs.size;
17165 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17167 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17168 ASSERT_VK_SUCCESS(err);
17170 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17171 memAlloc.allocationSize = memReqs.size;
17172 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17174 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17175 ASSERT_VK_SUCCESS(err);
17177 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17178 ASSERT_VK_SUCCESS(err);
17179 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17180 ASSERT_VK_SUCCESS(err);
17182 BeginCommandBuffer();
17183 VkImageCopy copyRegion;
17184 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17185 copyRegion.srcSubresource.mipLevel = 0;
17186 copyRegion.srcSubresource.baseArrayLayer = 0;
17187 copyRegion.srcSubresource.layerCount = 0;
17188 copyRegion.srcOffset.x = 0;
17189 copyRegion.srcOffset.y = 0;
17190 copyRegion.srcOffset.z = 0;
17191 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17192 copyRegion.dstSubresource.mipLevel = 0;
17193 copyRegion.dstSubresource.baseArrayLayer = 0;
17194 copyRegion.dstSubresource.layerCount = 0;
17195 copyRegion.dstOffset.x = 0;
17196 copyRegion.dstOffset.y = 0;
17197 copyRegion.dstOffset.z = 0;
17198 copyRegion.extent.width = 1;
17199 copyRegion.extent.height = 1;
17200 copyRegion.extent.depth = 1;
17201 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
17202 EndCommandBuffer();
17204 m_errorMonitor->VerifyFound();
17206 vkDestroyImage(m_device->device(), srcImage, NULL);
17207 vkDestroyImage(m_device->device(), dstImage, NULL);
17208 vkFreeMemory(m_device->device(), srcMem, NULL);
17209 vkFreeMemory(m_device->device(), destMem, NULL);
17212 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
17216 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17217 "vkCmdResolveImage called with source sample count less than 2.");
17219 ASSERT_NO_FATAL_FAILURE(InitState());
17221 // Create two images of sample count 1 and try to Resolve between them
17224 VkDeviceMemory srcMem;
17225 VkDeviceMemory destMem;
17226 VkMemoryRequirements memReqs;
17228 VkImageCreateInfo image_create_info = {};
17229 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17230 image_create_info.pNext = NULL;
17231 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17232 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17233 image_create_info.extent.width = 32;
17234 image_create_info.extent.height = 1;
17235 image_create_info.extent.depth = 1;
17236 image_create_info.mipLevels = 1;
17237 image_create_info.arrayLayers = 1;
17238 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17239 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17240 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17241 image_create_info.flags = 0;
17243 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17244 ASSERT_VK_SUCCESS(err);
17246 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17248 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17249 ASSERT_VK_SUCCESS(err);
17252 VkMemoryAllocateInfo memAlloc = {};
17253 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17254 memAlloc.pNext = NULL;
17255 memAlloc.allocationSize = 0;
17256 memAlloc.memoryTypeIndex = 0;
17258 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17259 memAlloc.allocationSize = memReqs.size;
17260 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17262 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17263 ASSERT_VK_SUCCESS(err);
17265 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17266 memAlloc.allocationSize = memReqs.size;
17267 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17269 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17270 ASSERT_VK_SUCCESS(err);
17272 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17273 ASSERT_VK_SUCCESS(err);
17274 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17275 ASSERT_VK_SUCCESS(err);
17277 BeginCommandBuffer();
17278 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17279 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17280 // VK_IMAGE_LAYOUT_GENERAL = 1,
17281 VkImageResolve resolveRegion;
17282 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17283 resolveRegion.srcSubresource.mipLevel = 0;
17284 resolveRegion.srcSubresource.baseArrayLayer = 0;
17285 resolveRegion.srcSubresource.layerCount = 1;
17286 resolveRegion.srcOffset.x = 0;
17287 resolveRegion.srcOffset.y = 0;
17288 resolveRegion.srcOffset.z = 0;
17289 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17290 resolveRegion.dstSubresource.mipLevel = 0;
17291 resolveRegion.dstSubresource.baseArrayLayer = 0;
17292 resolveRegion.dstSubresource.layerCount = 1;
17293 resolveRegion.dstOffset.x = 0;
17294 resolveRegion.dstOffset.y = 0;
17295 resolveRegion.dstOffset.z = 0;
17296 resolveRegion.extent.width = 1;
17297 resolveRegion.extent.height = 1;
17298 resolveRegion.extent.depth = 1;
17299 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17300 EndCommandBuffer();
17302 m_errorMonitor->VerifyFound();
17304 vkDestroyImage(m_device->device(), srcImage, NULL);
17305 vkDestroyImage(m_device->device(), dstImage, NULL);
17306 vkFreeMemory(m_device->device(), srcMem, NULL);
17307 vkFreeMemory(m_device->device(), destMem, NULL);
17310 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
17314 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17315 "vkCmdResolveImage called with dest sample count greater than 1.");
17317 ASSERT_NO_FATAL_FAILURE(InitState());
17319 // Create two images of sample count 4 and try to Resolve between them
17322 VkDeviceMemory srcMem;
17323 VkDeviceMemory destMem;
17324 VkMemoryRequirements memReqs;
17326 VkImageCreateInfo image_create_info = {};
17327 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17328 image_create_info.pNext = NULL;
17329 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17330 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17331 image_create_info.extent.width = 32;
17332 image_create_info.extent.height = 1;
17333 image_create_info.extent.depth = 1;
17334 image_create_info.mipLevels = 1;
17335 image_create_info.arrayLayers = 1;
17336 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
17337 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17338 // Note: Some implementations expect color attachment usage for any
17339 // multisample surface
17340 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17341 image_create_info.flags = 0;
17343 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17344 ASSERT_VK_SUCCESS(err);
17346 // Note: Some implementations expect color attachment usage for any
17347 // multisample surface
17348 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17350 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17351 ASSERT_VK_SUCCESS(err);
17354 VkMemoryAllocateInfo memAlloc = {};
17355 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17356 memAlloc.pNext = NULL;
17357 memAlloc.allocationSize = 0;
17358 memAlloc.memoryTypeIndex = 0;
17360 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17361 memAlloc.allocationSize = memReqs.size;
17362 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17364 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17365 ASSERT_VK_SUCCESS(err);
17367 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17368 memAlloc.allocationSize = memReqs.size;
17369 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17371 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17372 ASSERT_VK_SUCCESS(err);
17374 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17375 ASSERT_VK_SUCCESS(err);
17376 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17377 ASSERT_VK_SUCCESS(err);
17379 BeginCommandBuffer();
17380 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17381 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17382 // VK_IMAGE_LAYOUT_GENERAL = 1,
17383 VkImageResolve resolveRegion;
17384 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17385 resolveRegion.srcSubresource.mipLevel = 0;
17386 resolveRegion.srcSubresource.baseArrayLayer = 0;
17387 resolveRegion.srcSubresource.layerCount = 1;
17388 resolveRegion.srcOffset.x = 0;
17389 resolveRegion.srcOffset.y = 0;
17390 resolveRegion.srcOffset.z = 0;
17391 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17392 resolveRegion.dstSubresource.mipLevel = 0;
17393 resolveRegion.dstSubresource.baseArrayLayer = 0;
17394 resolveRegion.dstSubresource.layerCount = 1;
17395 resolveRegion.dstOffset.x = 0;
17396 resolveRegion.dstOffset.y = 0;
17397 resolveRegion.dstOffset.z = 0;
17398 resolveRegion.extent.width = 1;
17399 resolveRegion.extent.height = 1;
17400 resolveRegion.extent.depth = 1;
17401 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17402 EndCommandBuffer();
17404 m_errorMonitor->VerifyFound();
17406 vkDestroyImage(m_device->device(), srcImage, NULL);
17407 vkDestroyImage(m_device->device(), dstImage, NULL);
17408 vkFreeMemory(m_device->device(), srcMem, NULL);
17409 vkFreeMemory(m_device->device(), destMem, NULL);
17412 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
17416 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17417 "vkCmdResolveImage called with unmatched source and dest formats.");
17419 ASSERT_NO_FATAL_FAILURE(InitState());
17421 // Create two images of different types and try to copy between them
17424 VkDeviceMemory srcMem;
17425 VkDeviceMemory destMem;
17426 VkMemoryRequirements memReqs;
17428 VkImageCreateInfo image_create_info = {};
17429 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17430 image_create_info.pNext = NULL;
17431 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17432 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17433 image_create_info.extent.width = 32;
17434 image_create_info.extent.height = 1;
17435 image_create_info.extent.depth = 1;
17436 image_create_info.mipLevels = 1;
17437 image_create_info.arrayLayers = 1;
17438 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17439 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17440 // Note: Some implementations expect color attachment usage for any
17441 // multisample surface
17442 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17443 image_create_info.flags = 0;
17445 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17446 ASSERT_VK_SUCCESS(err);
17448 // Set format to something other than source image
17449 image_create_info.format = VK_FORMAT_R32_SFLOAT;
17450 // Note: Some implementations expect color attachment usage for any
17451 // multisample surface
17452 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17453 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17455 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17456 ASSERT_VK_SUCCESS(err);
17459 VkMemoryAllocateInfo memAlloc = {};
17460 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17461 memAlloc.pNext = NULL;
17462 memAlloc.allocationSize = 0;
17463 memAlloc.memoryTypeIndex = 0;
17465 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17466 memAlloc.allocationSize = memReqs.size;
17467 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17469 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17470 ASSERT_VK_SUCCESS(err);
17472 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17473 memAlloc.allocationSize = memReqs.size;
17474 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17476 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17477 ASSERT_VK_SUCCESS(err);
17479 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17480 ASSERT_VK_SUCCESS(err);
17481 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17482 ASSERT_VK_SUCCESS(err);
17484 BeginCommandBuffer();
17485 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17486 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17487 // VK_IMAGE_LAYOUT_GENERAL = 1,
17488 VkImageResolve resolveRegion;
17489 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17490 resolveRegion.srcSubresource.mipLevel = 0;
17491 resolveRegion.srcSubresource.baseArrayLayer = 0;
17492 resolveRegion.srcSubresource.layerCount = 1;
17493 resolveRegion.srcOffset.x = 0;
17494 resolveRegion.srcOffset.y = 0;
17495 resolveRegion.srcOffset.z = 0;
17496 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17497 resolveRegion.dstSubresource.mipLevel = 0;
17498 resolveRegion.dstSubresource.baseArrayLayer = 0;
17499 resolveRegion.dstSubresource.layerCount = 1;
17500 resolveRegion.dstOffset.x = 0;
17501 resolveRegion.dstOffset.y = 0;
17502 resolveRegion.dstOffset.z = 0;
17503 resolveRegion.extent.width = 1;
17504 resolveRegion.extent.height = 1;
17505 resolveRegion.extent.depth = 1;
17506 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17507 EndCommandBuffer();
17509 m_errorMonitor->VerifyFound();
17511 vkDestroyImage(m_device->device(), srcImage, NULL);
17512 vkDestroyImage(m_device->device(), dstImage, NULL);
17513 vkFreeMemory(m_device->device(), srcMem, NULL);
17514 vkFreeMemory(m_device->device(), destMem, NULL);
17517 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
17521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17522 "vkCmdResolveImage called with unmatched source and dest image types.");
17524 ASSERT_NO_FATAL_FAILURE(InitState());
17526 // Create two images of different types and try to copy between them
17529 VkDeviceMemory srcMem;
17530 VkDeviceMemory destMem;
17531 VkMemoryRequirements memReqs;
17533 VkImageCreateInfo image_create_info = {};
17534 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17535 image_create_info.pNext = NULL;
17536 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17537 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17538 image_create_info.extent.width = 32;
17539 image_create_info.extent.height = 1;
17540 image_create_info.extent.depth = 1;
17541 image_create_info.mipLevels = 1;
17542 image_create_info.arrayLayers = 1;
17543 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17544 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17545 // Note: Some implementations expect color attachment usage for any
17546 // multisample surface
17547 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17548 image_create_info.flags = 0;
17550 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17551 ASSERT_VK_SUCCESS(err);
17553 image_create_info.imageType = VK_IMAGE_TYPE_1D;
17554 // Note: Some implementations expect color attachment usage for any
17555 // multisample surface
17556 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17557 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17559 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17560 ASSERT_VK_SUCCESS(err);
17563 VkMemoryAllocateInfo memAlloc = {};
17564 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17565 memAlloc.pNext = NULL;
17566 memAlloc.allocationSize = 0;
17567 memAlloc.memoryTypeIndex = 0;
17569 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17570 memAlloc.allocationSize = memReqs.size;
17571 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17573 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17574 ASSERT_VK_SUCCESS(err);
17576 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17577 memAlloc.allocationSize = memReqs.size;
17578 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17580 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17581 ASSERT_VK_SUCCESS(err);
17583 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17584 ASSERT_VK_SUCCESS(err);
17585 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17586 ASSERT_VK_SUCCESS(err);
17588 BeginCommandBuffer();
17589 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17590 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17591 // VK_IMAGE_LAYOUT_GENERAL = 1,
17592 VkImageResolve resolveRegion;
17593 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17594 resolveRegion.srcSubresource.mipLevel = 0;
17595 resolveRegion.srcSubresource.baseArrayLayer = 0;
17596 resolveRegion.srcSubresource.layerCount = 1;
17597 resolveRegion.srcOffset.x = 0;
17598 resolveRegion.srcOffset.y = 0;
17599 resolveRegion.srcOffset.z = 0;
17600 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17601 resolveRegion.dstSubresource.mipLevel = 0;
17602 resolveRegion.dstSubresource.baseArrayLayer = 0;
17603 resolveRegion.dstSubresource.layerCount = 1;
17604 resolveRegion.dstOffset.x = 0;
17605 resolveRegion.dstOffset.y = 0;
17606 resolveRegion.dstOffset.z = 0;
17607 resolveRegion.extent.width = 1;
17608 resolveRegion.extent.height = 1;
17609 resolveRegion.extent.depth = 1;
17610 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17611 EndCommandBuffer();
17613 m_errorMonitor->VerifyFound();
17615 vkDestroyImage(m_device->device(), srcImage, NULL);
17616 vkDestroyImage(m_device->device(), dstImage, NULL);
17617 vkFreeMemory(m_device->device(), srcMem, NULL);
17618 vkFreeMemory(m_device->device(), destMem, NULL);
17621 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
17622 // Create a single Image descriptor and cause it to first hit an error due
17623 // to using a DS format, then cause it to hit error due to COLOR_BIT not
17625 // The image format check comes 2nd in validation so we trigger it first,
17626 // then when we cause aspect fail next, bad format check will be preempted
17629 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17630 "Combination depth/stencil image formats can have only the ");
17632 ASSERT_NO_FATAL_FAILURE(InitState());
17634 VkDescriptorPoolSize ds_type_count = {};
17635 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17636 ds_type_count.descriptorCount = 1;
17638 VkDescriptorPoolCreateInfo ds_pool_ci = {};
17639 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
17640 ds_pool_ci.pNext = NULL;
17641 ds_pool_ci.maxSets = 1;
17642 ds_pool_ci.poolSizeCount = 1;
17643 ds_pool_ci.pPoolSizes = &ds_type_count;
17645 VkDescriptorPool ds_pool;
17646 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
17647 ASSERT_VK_SUCCESS(err);
17649 VkDescriptorSetLayoutBinding dsl_binding = {};
17650 dsl_binding.binding = 0;
17651 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17652 dsl_binding.descriptorCount = 1;
17653 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
17654 dsl_binding.pImmutableSamplers = NULL;
17656 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
17657 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
17658 ds_layout_ci.pNext = NULL;
17659 ds_layout_ci.bindingCount = 1;
17660 ds_layout_ci.pBindings = &dsl_binding;
17661 VkDescriptorSetLayout ds_layout;
17662 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
17663 ASSERT_VK_SUCCESS(err);
17665 VkDescriptorSet descriptorSet;
17666 VkDescriptorSetAllocateInfo alloc_info = {};
17667 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
17668 alloc_info.descriptorSetCount = 1;
17669 alloc_info.descriptorPool = ds_pool;
17670 alloc_info.pSetLayouts = &ds_layout;
17671 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
17672 ASSERT_VK_SUCCESS(err);
17675 VkImage image_good;
17676 // One bad format and one good format for Color attachment
17677 const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
17678 const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
17679 const int32_t tex_width = 32;
17680 const int32_t tex_height = 32;
17682 VkImageCreateInfo image_create_info = {};
17683 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17684 image_create_info.pNext = NULL;
17685 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17686 image_create_info.format = tex_format_bad;
17687 image_create_info.extent.width = tex_width;
17688 image_create_info.extent.height = tex_height;
17689 image_create_info.extent.depth = 1;
17690 image_create_info.mipLevels = 1;
17691 image_create_info.arrayLayers = 1;
17692 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17693 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17694 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17695 image_create_info.flags = 0;
17697 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
17698 ASSERT_VK_SUCCESS(err);
17699 image_create_info.format = tex_format_good;
17700 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17701 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
17702 ASSERT_VK_SUCCESS(err);
17704 VkImageViewCreateInfo image_view_create_info = {};
17705 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17706 image_view_create_info.image = image_bad;
17707 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
17708 image_view_create_info.format = tex_format_bad;
17709 image_view_create_info.subresourceRange.baseArrayLayer = 0;
17710 image_view_create_info.subresourceRange.baseMipLevel = 0;
17711 image_view_create_info.subresourceRange.layerCount = 1;
17712 image_view_create_info.subresourceRange.levelCount = 1;
17713 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17716 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
17718 m_errorMonitor->VerifyFound();
17720 vkDestroyImage(m_device->device(), image_bad, NULL);
17721 vkDestroyImage(m_device->device(), image_good, NULL);
17722 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
17723 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
17726 TEST_F(VkLayerTest, ClearImageErrors) {
17727 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and "
17728 "ClearDepthStencilImage with a color image.");
17730 ASSERT_NO_FATAL_FAILURE(InitState());
17731 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17733 // Renderpass is started here so end it as Clear cmds can't be in renderpass
17734 BeginCommandBuffer();
17735 m_commandBuffer->EndRenderPass();
17738 VkClearColorValue clear_color;
17739 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
17740 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
17741 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
17742 const int32_t img_width = 32;
17743 const int32_t img_height = 32;
17744 VkImageCreateInfo image_create_info = {};
17745 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17746 image_create_info.pNext = NULL;
17747 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17748 image_create_info.format = color_format;
17749 image_create_info.extent.width = img_width;
17750 image_create_info.extent.height = img_height;
17751 image_create_info.extent.depth = 1;
17752 image_create_info.mipLevels = 1;
17753 image_create_info.arrayLayers = 1;
17754 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17755 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17756 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
17758 vk_testing::Image color_image;
17759 color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
17761 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
17763 // Depth/Stencil image
17764 VkClearDepthStencilValue clear_value = {0};
17765 reqs = 0; // don't need HOST_VISIBLE DS image
17766 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
17767 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
17768 ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17769 ds_image_create_info.extent.width = 64;
17770 ds_image_create_info.extent.height = 64;
17771 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17772 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17774 vk_testing::Image ds_image;
17775 ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs);
17777 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
17779 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
17781 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17784 m_errorMonitor->VerifyFound();
17786 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with "
17787 "image created without "
17788 "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
17790 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17793 m_errorMonitor->VerifyFound();
17795 // Call CmdClearDepthStencilImage with color image
17796 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17797 "vkCmdClearDepthStencilImage called without a depth/stencil image.");
17799 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(),
17800 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range);
17802 m_errorMonitor->VerifyFound();
17804 #endif // IMAGE_TESTS
17806 #if defined(ANDROID) && defined(VALIDATION_APK)
17807 static bool initialized = false;
17808 static bool active = false;
17810 // Convert Intents to argv
17811 // Ported from Hologram sample, only difference is flexible key
17812 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
17813 std::vector<std::string> args;
17814 JavaVM &vm = *app.activity->vm;
17816 if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
17819 JNIEnv &env = *p_env;
17820 jobject activity = app.activity->clazz;
17821 jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
17822 jobject intent = env.CallObjectMethod(activity, get_intent_method);
17823 jmethodID get_string_extra_method =
17824 env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
17825 jvalue get_string_extra_args;
17826 get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
17827 jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
17829 std::string args_str;
17831 const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
17832 args_str = extra_utf;
17833 env.ReleaseStringUTFChars(extra_str, extra_utf);
17834 env.DeleteLocalRef(extra_str);
17837 env.DeleteLocalRef(get_string_extra_args.l);
17838 env.DeleteLocalRef(intent);
17839 vm.DetachCurrentThread();
17842 std::stringstream ss(args_str);
17844 while (std::getline(ss, arg, ' ')) {
17846 args.push_back(arg);
17852 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
17854 static void processCommand(struct android_app *app, int32_t cmd) {
17856 case APP_CMD_INIT_WINDOW: {
17858 initialized = true;
17862 case APP_CMD_GAINED_FOCUS: {
17866 case APP_CMD_LOST_FOCUS: {
17873 void android_main(struct android_app *app) {
17876 const char *appTag = "VulkanLayerValidationTests";
17878 int vulkanSupport = InitVulkan();
17879 if (vulkanSupport == 0) {
17880 __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
17884 app->onAppCmd = processCommand;
17885 app->onInputEvent = processInput;
17889 struct android_poll_source *source;
17890 while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
17892 source->process(app, source);
17895 if (app->destroyRequested != 0) {
17896 VkTestFramework::Finish();
17901 if (initialized && active) {
17902 // Use the following key to send arguments to gtest, i.e.
17903 // --es args "--gtest_filter=-VkLayerTest.foo"
17904 const char key[] = "args";
17905 std::vector<std::string> args = get_args(*app, key);
17907 std::string filter = "";
17908 if (args.size() > 0) {
17909 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
17912 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
17916 char *argv[] = {(char *)"foo", (char *)filter.c_str()};
17917 __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
17919 // Route output to files until we can override the gtest output
17920 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
17921 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
17923 ::testing::InitGoogleTest(&argc, argv);
17924 VkTestFramework::InitArgs(&argc, argv);
17925 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17927 int result = RUN_ALL_TESTS();
17930 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
17932 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
17935 VkTestFramework::Finish();
17940 ANativeActivity_finish(app->activity);
17948 int main(int argc, char **argv) {
17952 int vulkanSupport = InitVulkan();
17953 if (vulkanSupport == 0)
17957 ::testing::InitGoogleTest(&argc, argv);
17958 VkTestFramework::InitArgs(&argc, argv);
17960 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17962 result = RUN_ALL_TESTS();
17964 VkTestFramework::Finish();