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 swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2468 swapchain_create_info.surface = surface;
2469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2470 "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
2471 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2472 pass = (err != VK_SUCCESS);
2474 m_errorMonitor->VerifyFound();
2476 // Get the surface capabilities:
2477 VkSurfaceCapabilitiesKHR surface_capabilities;
2479 // Do so correctly (only error logged by this entrypoint is if the
2480 // extension isn't enabled):
2481 err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
2482 pass = (err == VK_SUCCESS);
2485 // Get the surface formats:
2486 uint32_t surface_format_count;
2488 // First, try without a pointer to surface_format_count:
2489 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
2490 "specified as NULL");
2491 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
2492 pass = (err == VK_SUCCESS);
2494 m_errorMonitor->VerifyFound();
2496 // Next, call with a non-NULL pSurfaceFormats, even though we haven't
2497 // correctly done a 1st try (to get the count):
2498 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2499 surface_format_count = 0;
2500 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
2501 pass = (err == VK_SUCCESS);
2503 m_errorMonitor->VerifyFound();
2505 // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2506 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2507 pass = (err == VK_SUCCESS);
2510 // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2511 VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
2513 // Next, do a 2nd try with surface_format_count being set too high:
2514 surface_format_count += 5;
2515 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2516 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2517 pass = (err == VK_SUCCESS);
2519 m_errorMonitor->VerifyFound();
2521 // Finally, do a correct 1st and 2nd try:
2522 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
2523 pass = (err == VK_SUCCESS);
2525 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
2526 pass = (err == VK_SUCCESS);
2529 // Get the surface present modes:
2530 uint32_t surface_present_mode_count;
2532 // First, try without a pointer to surface_format_count:
2533 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
2534 "specified as NULL");
2536 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
2537 pass = (err == VK_SUCCESS);
2539 m_errorMonitor->VerifyFound();
2541 // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
2542 // correctly done a 1st try (to get the count):
2543 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
2544 surface_present_mode_count = 0;
2545 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
2546 (VkPresentModeKHR *)&surface_present_mode_count);
2547 pass = (err == VK_SUCCESS);
2549 m_errorMonitor->VerifyFound();
2551 // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
2552 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2553 pass = (err == VK_SUCCESS);
2556 // Allocate memory for the correct number of VkSurfaceFormatKHR's:
2557 VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
2559 // Next, do a 2nd try with surface_format_count being set too high:
2560 surface_present_mode_count += 5;
2561 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
2562 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2563 pass = (err == VK_SUCCESS);
2565 m_errorMonitor->VerifyFound();
2567 // Finally, do a correct 1st and 2nd try:
2568 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
2569 pass = (err == VK_SUCCESS);
2571 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
2572 pass = (err == VK_SUCCESS);
2575 // Create a swapchain:
2577 // First, try without a pointer to swapchain_create_info:
2578 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
2579 "specified as NULL");
2581 err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
2582 pass = (err != VK_SUCCESS);
2584 m_errorMonitor->VerifyFound();
2586 // Next, call with a non-NULL swapchain_create_info, that has the wrong
2588 swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2589 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
2591 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2592 pass = (err != VK_SUCCESS);
2594 m_errorMonitor->VerifyFound();
2596 // Next, call with a NULL swapchain pointer:
2597 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
2598 swapchain_create_info.pNext = NULL;
2599 swapchain_create_info.flags = 0;
2600 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
2601 "specified as NULL");
2603 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
2604 pass = (err != VK_SUCCESS);
2606 m_errorMonitor->VerifyFound();
2608 // TODO: Enhance swapchain layer so that
2609 // swapchain_create_info.queueFamilyIndexCount is checked against something?
2611 // Next, call with a queue family index that's too large:
2612 uint32_t queueFamilyIndex[2] = {100000, 0};
2613 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2614 swapchain_create_info.queueFamilyIndexCount = 2;
2615 swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
2616 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
2617 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2618 pass = (err != VK_SUCCESS);
2620 m_errorMonitor->VerifyFound();
2622 // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
2623 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
2624 swapchain_create_info.queueFamilyIndexCount = 1;
2625 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2626 "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
2627 "pCreateInfo->pQueueFamilyIndices).");
2628 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2629 pass = (err != VK_SUCCESS);
2631 m_errorMonitor->VerifyFound();
2633 // Next, call with an invalid imageSharingMode:
2634 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
2635 swapchain_create_info.queueFamilyIndexCount = 1;
2636 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2637 "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
2638 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
2639 pass = (err != VK_SUCCESS);
2641 m_errorMonitor->VerifyFound();
2642 // Fix for the future:
2643 // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
2645 swapchain_create_info.queueFamilyIndexCount = 0;
2646 queueFamilyIndex[0] = 0;
2647 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
2649 // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
2650 // Get the images from a swapchain:
2651 // Acquire an image from a swapchain:
2652 // Present an image to a swapchain:
2653 // Destroy the swapchain:
2657 // - Try destroying the device without first destroying the swapchain
2659 // - Try destroying the device without first destroying the surface
2661 // - Try destroying the surface without first destroying the swapchain
2663 // Destroy the surface:
2664 vkDestroySurfaceKHR(instance(), surface, NULL);
2666 // Tear down the window:
2667 xcb_destroy_window(connection, xcb_window);
2668 xcb_disconnect(connection);
2670 #else // VK_USE_PLATFORM_XCB_KHR
2672 #endif // VK_USE_PLATFORM_XCB_KHR
2675 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2679 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2680 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2682 ASSERT_NO_FATAL_FAILURE(InitState());
2684 // Create an image, allocate memory, free it, and then try to bind it
2687 VkMemoryRequirements mem_reqs;
2689 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2690 const int32_t tex_width = 32;
2691 const int32_t tex_height = 32;
2693 VkImageCreateInfo image_create_info = {};
2694 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2695 image_create_info.pNext = NULL;
2696 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2697 image_create_info.format = tex_format;
2698 image_create_info.extent.width = tex_width;
2699 image_create_info.extent.height = tex_height;
2700 image_create_info.extent.depth = 1;
2701 image_create_info.mipLevels = 1;
2702 image_create_info.arrayLayers = 1;
2703 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2704 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2705 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2706 image_create_info.flags = 0;
2707 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2709 VkMemoryAllocateInfo mem_alloc = {};
2710 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2711 mem_alloc.pNext = NULL;
2712 mem_alloc.allocationSize = 0;
2714 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2715 ASSERT_VK_SUCCESS(err);
2717 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2719 mem_alloc.allocationSize = mem_reqs.size;
2721 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2722 if (!pass) { // If we can't find any unmappable memory this test doesn't
2724 vkDestroyImage(m_device->device(), image, NULL);
2729 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2730 ASSERT_VK_SUCCESS(err);
2732 // Try to bind free memory that has been freed
2733 err = vkBindImageMemory(m_device->device(), image, mem, 0);
2734 ASSERT_VK_SUCCESS(err);
2736 // Map memory as if to initialize the image
2737 void *mappedAddress = NULL;
2738 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2740 m_errorMonitor->VerifyFound();
2742 vkDestroyImage(m_device->device(), image, NULL);
2743 vkFreeMemory(m_device->device(), mem, NULL);
2746 TEST_F(VkLayerTest, RebindMemory) {
2750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2752 ASSERT_NO_FATAL_FAILURE(InitState());
2754 // Create an image, allocate memory, free it, and then try to bind it
2756 VkDeviceMemory mem1;
2757 VkDeviceMemory mem2;
2758 VkMemoryRequirements mem_reqs;
2760 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2761 const int32_t tex_width = 32;
2762 const int32_t tex_height = 32;
2764 VkImageCreateInfo image_create_info = {};
2765 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2766 image_create_info.pNext = NULL;
2767 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2768 image_create_info.format = tex_format;
2769 image_create_info.extent.width = tex_width;
2770 image_create_info.extent.height = tex_height;
2771 image_create_info.extent.depth = 1;
2772 image_create_info.mipLevels = 1;
2773 image_create_info.arrayLayers = 1;
2774 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2775 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2776 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2777 image_create_info.flags = 0;
2779 VkMemoryAllocateInfo mem_alloc = {};
2780 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2781 mem_alloc.pNext = NULL;
2782 mem_alloc.allocationSize = 0;
2783 mem_alloc.memoryTypeIndex = 0;
2785 // Introduce failure, do NOT set memProps to
2786 // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2787 mem_alloc.memoryTypeIndex = 1;
2788 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2789 ASSERT_VK_SUCCESS(err);
2791 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2793 mem_alloc.allocationSize = mem_reqs.size;
2794 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2797 // allocate 2 memory objects
2798 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2799 ASSERT_VK_SUCCESS(err);
2800 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2801 ASSERT_VK_SUCCESS(err);
2803 // Bind first memory object to Image object
2804 err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2805 ASSERT_VK_SUCCESS(err);
2807 // Introduce validation failure, try to bind a different memory object to
2808 // the same image object
2809 err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2811 m_errorMonitor->VerifyFound();
2813 vkDestroyImage(m_device->device(), image, NULL);
2814 vkFreeMemory(m_device->device(), mem1, NULL);
2815 vkFreeMemory(m_device->device(), mem2, NULL);
2818 TEST_F(VkLayerTest, SubmitSignaledFence) {
2819 vk_testing::Fence testFence;
2821 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state. Fences "
2822 "must be reset before being submitted");
2824 VkFenceCreateInfo fenceInfo = {};
2825 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2826 fenceInfo.pNext = NULL;
2827 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2829 ASSERT_NO_FATAL_FAILURE(InitState());
2830 ASSERT_NO_FATAL_FAILURE(InitViewport());
2831 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2833 BeginCommandBuffer();
2834 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
2837 testFence.init(*m_device, fenceInfo);
2839 VkSubmitInfo submit_info;
2840 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2841 submit_info.pNext = NULL;
2842 submit_info.waitSemaphoreCount = 0;
2843 submit_info.pWaitSemaphores = NULL;
2844 submit_info.pWaitDstStageMask = NULL;
2845 submit_info.commandBufferCount = 1;
2846 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2847 submit_info.signalSemaphoreCount = 0;
2848 submit_info.pSignalSemaphores = NULL;
2850 vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2851 vkQueueWaitIdle(m_device->m_queue);
2853 m_errorMonitor->VerifyFound();
2855 // This is a positive test. We used to expect error in this case but spec now
2857 TEST_F(VkLayerTest, ResetUnsignaledFence) {
2858 m_errorMonitor->ExpectSuccess();
2859 vk_testing::Fence testFence;
2860 VkFenceCreateInfo fenceInfo = {};
2861 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2862 fenceInfo.pNext = NULL;
2864 ASSERT_NO_FATAL_FAILURE(InitState());
2865 testFence.init(*m_device, fenceInfo);
2866 VkFence fences[1] = {testFence.handle()};
2867 VkResult result = vkResetFences(m_device->device(), 1, fences);
2868 ASSERT_VK_SUCCESS(result);
2870 m_errorMonitor->VerifyNotFound();
2872 #if 0 // A few devices have issues with this test so disabling for now
2873 TEST_F(VkLayerTest, LongFenceChain)
2875 m_errorMonitor->ExpectSuccess();
2877 ASSERT_NO_FATAL_FAILURE(InitState());
2880 std::vector<VkFence> fences;
2882 const int chainLength = 32768;
2884 for (int i = 0; i < chainLength; i++) {
2885 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
2887 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2888 ASSERT_VK_SUCCESS(err);
2890 fences.push_back(fence);
2892 VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
2893 0, nullptr, 0, nullptr };
2894 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2895 ASSERT_VK_SUCCESS(err);
2899 // BOOM, stack overflow.
2900 vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
2902 for (auto fence : fences)
2903 vkDestroyFence(m_device->device(), fence, nullptr);
2905 m_errorMonitor->VerifyNotFound();
2908 TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
2909 m_errorMonitor->ExpectSuccess();
2911 ASSERT_NO_FATAL_FAILURE(InitState());
2914 // Record (empty!) command buffer that can be submitted multiple times
2916 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2917 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
2918 m_commandBuffer->BeginCommandBuffer(&cbbi);
2919 m_commandBuffer->EndCommandBuffer();
2921 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2923 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
2924 ASSERT_VK_SUCCESS(err);
2926 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
2928 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
2929 ASSERT_VK_SUCCESS(err);
2930 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
2931 ASSERT_VK_SUCCESS(err);
2933 // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
2934 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
2935 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
2936 ASSERT_VK_SUCCESS(err);
2938 // Submit CB again, signaling s2.
2939 si.pSignalSemaphores = &s2;
2940 err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2941 ASSERT_VK_SUCCESS(err);
2944 err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
2945 ASSERT_VK_SUCCESS(err);
2947 // CB is still in flight from second submission, but semaphore s1 is no
2948 // longer in flight. delete it.
2949 vkDestroySemaphore(m_device->device(), s1, nullptr);
2951 m_errorMonitor->VerifyNotFound();
2953 // Force device idle and clean up remaining objects
2954 vkDeviceWaitIdle(m_device->device());
2955 vkDestroySemaphore(m_device->device(), s2, nullptr);
2956 vkDestroyFence(m_device->device(), fence, nullptr);
2959 TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
2960 m_errorMonitor->ExpectSuccess();
2962 ASSERT_NO_FATAL_FAILURE(InitState());
2965 // A fence created signaled
2966 VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
2968 err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
2969 ASSERT_VK_SUCCESS(err);
2971 // A fence created not
2972 VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
2974 err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
2975 ASSERT_VK_SUCCESS(err);
2977 // Submit the unsignaled fence
2978 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
2979 err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
2981 // Wait on both fences, with signaled first.
2982 VkFence fences[] = {f1, f2};
2983 vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
2985 // Should have both retired!
2986 vkDestroyFence(m_device->device(), f1, nullptr);
2987 vkDestroyFence(m_device->device(), f2, nullptr);
2989 m_errorMonitor->VerifyNotFound();
2992 TEST_F(VkLayerTest, InvalidUsageBits) {
2993 TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
2994 "Initialize buffer with wrong usage then perform copy expecting errors "
2995 "from both the image and the buffer (2 calls)");
2996 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
2998 ASSERT_NO_FATAL_FAILURE(InitState());
2999 VkImageObj image(m_device);
3000 // Initialize image with USAGE_TRANSIENT_ATTACHMENT
3001 image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3002 ASSERT_TRUE(image.initialized());
3005 VkImageViewCreateInfo dsvci = {};
3006 dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3007 dsvci.image = image.handle();
3008 dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3009 dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
3010 dsvci.subresourceRange.layerCount = 1;
3011 dsvci.subresourceRange.baseMipLevel = 0;
3012 dsvci.subresourceRange.levelCount = 1;
3013 dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3015 // Create a view with depth / stencil aspect for image with different usage
3016 vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3018 m_errorMonitor->VerifyFound();
3020 // Initialize buffer with TRANSFER_DST usage
3021 vk_testing::Buffer buffer;
3022 VkMemoryPropertyFlags reqs = 0;
3023 buffer.init_as_dst(*m_device, 128 * 128, reqs);
3024 VkBufferImageCopy region = {};
3025 region.bufferRowLength = 128;
3026 region.bufferImageHeight = 128;
3027 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3028 region.imageSubresource.layerCount = 1;
3029 region.imageExtent.height = 16;
3030 region.imageExtent.width = 16;
3031 region.imageExtent.depth = 1;
3033 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
3034 // Buffer usage not set to TRANSFER_SRC and image usage not set to
3036 BeginCommandBuffer();
3037 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3038 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
3039 m_errorMonitor->VerifyFound();
3041 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
3042 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
3043 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
3044 m_errorMonitor->VerifyFound();
3047 TEST_F(VkLayerTest, ValidUsage) {
3048 TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
3049 "doesn't generate validation errors");
3051 ASSERT_NO_FATAL_FAILURE(InitState());
3053 m_errorMonitor->ExpectSuccess();
3054 // Verify that we can create a view with usage INPUT_ATTACHMENT
3055 VkImageObj image(m_device);
3056 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3057 ASSERT_TRUE(image.initialized());
3058 VkImageView imageView;
3059 VkImageViewCreateInfo ivci = {};
3060 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3061 ivci.image = image.handle();
3062 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3063 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3064 ivci.subresourceRange.layerCount = 1;
3065 ivci.subresourceRange.baseMipLevel = 0;
3066 ivci.subresourceRange.levelCount = 1;
3067 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3069 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3070 m_errorMonitor->VerifyNotFound();
3071 vkDestroyImageView(m_device->device(), imageView, NULL);
3073 #endif // MEM_TRACKER_TESTS
3075 #if OBJ_TRACKER_TESTS
3077 TEST_F(VkLayerTest, LeakAnObject) {
3080 TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3082 // Note that we have to create a new device since destroying the
3083 // framework's device causes Teardown() to fail and just calling Teardown
3084 // will destroy the errorMonitor.
3086 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3088 ASSERT_NO_FATAL_FAILURE(InitState());
3090 const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
3091 std::vector<VkDeviceQueueCreateInfo> queue_info;
3092 queue_info.reserve(queue_props.size());
3093 std::vector<std::vector<float>> queue_priorities;
3094 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
3095 VkDeviceQueueCreateInfo qi = {};
3096 qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3098 qi.queueFamilyIndex = i;
3099 qi.queueCount = queue_props[i].queueCount;
3100 queue_priorities.emplace_back(qi.queueCount, 0.0f);
3101 qi.pQueuePriorities = queue_priorities[i].data();
3102 queue_info.push_back(qi);
3105 std::vector<const char *> device_extension_names;
3107 // The sacrificial device object
3108 VkDevice testDevice;
3109 VkDeviceCreateInfo device_create_info = {};
3110 auto features = m_device->phy().features();
3111 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3112 device_create_info.pNext = NULL;
3113 device_create_info.queueCreateInfoCount = queue_info.size();
3114 device_create_info.pQueueCreateInfos = queue_info.data();
3115 device_create_info.enabledLayerCount = 0;
3116 device_create_info.ppEnabledLayerNames = NULL;
3117 device_create_info.pEnabledFeatures = &features;
3118 err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3119 ASSERT_VK_SUCCESS(err);
3122 VkFenceCreateInfo fence_create_info = {};
3123 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3124 fence_create_info.pNext = NULL;
3125 fence_create_info.flags = 0;
3126 err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3127 ASSERT_VK_SUCCESS(err);
3129 // Induce failure by not calling vkDestroyFence
3130 vkDestroyDevice(testDevice, NULL);
3131 m_errorMonitor->VerifyFound();
3134 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3136 TEST_DESCRIPTION("Allocate command buffers from one command pool and "
3137 "attempt to delete them from another.");
3139 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3141 ASSERT_NO_FATAL_FAILURE(InitState());
3142 VkCommandPool command_pool_one;
3143 VkCommandPool command_pool_two;
3145 VkCommandPoolCreateInfo pool_create_info{};
3146 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3147 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3148 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3150 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3152 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3154 VkCommandBuffer command_buffer[9];
3155 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3156 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3157 command_buffer_allocate_info.commandPool = command_pool_one;
3158 command_buffer_allocate_info.commandBufferCount = 9;
3159 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3160 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3162 vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]);
3164 m_errorMonitor->VerifyFound();
3166 vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3167 vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3170 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3173 TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and "
3174 "attempt to delete them from another.");
3176 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3178 ASSERT_NO_FATAL_FAILURE(InitState());
3179 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3181 VkDescriptorPoolSize ds_type_count = {};
3182 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3183 ds_type_count.descriptorCount = 1;
3185 VkDescriptorPoolCreateInfo ds_pool_ci = {};
3186 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3187 ds_pool_ci.pNext = NULL;
3188 ds_pool_ci.flags = 0;
3189 ds_pool_ci.maxSets = 1;
3190 ds_pool_ci.poolSizeCount = 1;
3191 ds_pool_ci.pPoolSizes = &ds_type_count;
3193 VkDescriptorPool ds_pool_one;
3194 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
3195 ASSERT_VK_SUCCESS(err);
3197 // Create a second descriptor pool
3198 VkDescriptorPool ds_pool_two;
3199 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two);
3200 ASSERT_VK_SUCCESS(err);
3202 VkDescriptorSetLayoutBinding dsl_binding = {};
3203 dsl_binding.binding = 0;
3204 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3205 dsl_binding.descriptorCount = 1;
3206 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3207 dsl_binding.pImmutableSamplers = NULL;
3209 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3210 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3211 ds_layout_ci.pNext = NULL;
3212 ds_layout_ci.bindingCount = 1;
3213 ds_layout_ci.pBindings = &dsl_binding;
3215 VkDescriptorSetLayout ds_layout;
3216 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3217 ASSERT_VK_SUCCESS(err);
3219 VkDescriptorSet descriptorSet;
3220 VkDescriptorSetAllocateInfo alloc_info = {};
3221 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3222 alloc_info.descriptorSetCount = 1;
3223 alloc_info.descriptorPool = ds_pool_one;
3224 alloc_info.pSetLayouts = &ds_layout;
3225 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3226 ASSERT_VK_SUCCESS(err);
3228 err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet);
3230 m_errorMonitor->VerifyFound();
3232 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3233 vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
3234 vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL);
3237 TEST_F(VkLayerTest, CreateUnknownObject) {
3238 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3240 TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3242 ASSERT_NO_FATAL_FAILURE(InitState());
3244 // Pass bogus handle into GetImageMemoryRequirements
3245 VkMemoryRequirements mem_reqs;
3246 uint64_t fakeImageHandle = 0xCADECADE;
3247 VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3249 vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3251 m_errorMonitor->VerifyFound();
3254 TEST_F(VkLayerTest, PipelineNotBound) {
3257 TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3259 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object ");
3261 ASSERT_NO_FATAL_FAILURE(InitState());
3262 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3264 VkDescriptorPoolSize ds_type_count = {};
3265 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3266 ds_type_count.descriptorCount = 1;
3268 VkDescriptorPoolCreateInfo ds_pool_ci = {};
3269 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3270 ds_pool_ci.pNext = NULL;
3271 ds_pool_ci.maxSets = 1;
3272 ds_pool_ci.poolSizeCount = 1;
3273 ds_pool_ci.pPoolSizes = &ds_type_count;
3275 VkDescriptorPool ds_pool;
3276 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
3277 ASSERT_VK_SUCCESS(err);
3279 VkDescriptorSetLayoutBinding dsl_binding = {};
3280 dsl_binding.binding = 0;
3281 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3282 dsl_binding.descriptorCount = 1;
3283 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
3284 dsl_binding.pImmutableSamplers = NULL;
3286 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
3287 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3288 ds_layout_ci.pNext = NULL;
3289 ds_layout_ci.bindingCount = 1;
3290 ds_layout_ci.pBindings = &dsl_binding;
3292 VkDescriptorSetLayout ds_layout;
3293 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
3294 ASSERT_VK_SUCCESS(err);
3296 VkDescriptorSet descriptorSet;
3297 VkDescriptorSetAllocateInfo alloc_info = {};
3298 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
3299 alloc_info.descriptorSetCount = 1;
3300 alloc_info.descriptorPool = ds_pool;
3301 alloc_info.pSetLayouts = &ds_layout;
3302 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
3303 ASSERT_VK_SUCCESS(err);
3305 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
3306 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3307 pipeline_layout_ci.pNext = NULL;
3308 pipeline_layout_ci.setLayoutCount = 1;
3309 pipeline_layout_ci.pSetLayouts = &ds_layout;
3311 VkPipelineLayout pipeline_layout;
3312 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
3313 ASSERT_VK_SUCCESS(err);
3315 VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3317 BeginCommandBuffer();
3318 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3320 m_errorMonitor->VerifyFound();
3322 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
3323 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
3324 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
3327 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3330 TEST_DESCRIPTION("Test validation check for an invalid memory type index "
3331 "during bind[Buffer|Image]Memory time");
3333 ASSERT_NO_FATAL_FAILURE(InitState());
3335 // Create an image, allocate memory, set a bad typeIndex and then try to
3339 VkMemoryRequirements mem_reqs;
3340 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3341 const int32_t tex_width = 32;
3342 const int32_t tex_height = 32;
3344 VkImageCreateInfo image_create_info = {};
3345 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3346 image_create_info.pNext = NULL;
3347 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3348 image_create_info.format = tex_format;
3349 image_create_info.extent.width = tex_width;
3350 image_create_info.extent.height = tex_height;
3351 image_create_info.extent.depth = 1;
3352 image_create_info.mipLevels = 1;
3353 image_create_info.arrayLayers = 1;
3354 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3355 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3356 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3357 image_create_info.flags = 0;
3359 VkMemoryAllocateInfo mem_alloc = {};
3360 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3361 mem_alloc.pNext = NULL;
3362 mem_alloc.allocationSize = 0;
3363 mem_alloc.memoryTypeIndex = 0;
3365 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3366 ASSERT_VK_SUCCESS(err);
3368 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3369 mem_alloc.allocationSize = mem_reqs.size;
3371 // Introduce Failure, select invalid TypeIndex
3372 VkPhysicalDeviceMemoryProperties memory_info;
3374 vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3376 for (i = 0; i < memory_info.memoryTypeCount; i++) {
3377 if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3378 mem_alloc.memoryTypeIndex = i;
3382 if (i >= memory_info.memoryTypeCount) {
3383 printf("No invalid memory type index could be found; skipped.\n");
3384 vkDestroyImage(m_device->device(), image, NULL);
3388 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3390 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3391 ASSERT_VK_SUCCESS(err);
3393 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3396 m_errorMonitor->VerifyFound();
3398 vkDestroyImage(m_device->device(), image, NULL);
3399 vkFreeMemory(m_device->device(), mem, NULL);
3402 TEST_F(VkLayerTest, BindInvalidMemory) {
3406 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object ");
3408 ASSERT_NO_FATAL_FAILURE(InitState());
3410 // Create an image, allocate memory, free it, and then try to bind it
3413 VkMemoryRequirements mem_reqs;
3415 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3416 const int32_t tex_width = 32;
3417 const int32_t tex_height = 32;
3419 VkImageCreateInfo image_create_info = {};
3420 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3421 image_create_info.pNext = NULL;
3422 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3423 image_create_info.format = tex_format;
3424 image_create_info.extent.width = tex_width;
3425 image_create_info.extent.height = tex_height;
3426 image_create_info.extent.depth = 1;
3427 image_create_info.mipLevels = 1;
3428 image_create_info.arrayLayers = 1;
3429 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3430 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3431 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3432 image_create_info.flags = 0;
3434 VkMemoryAllocateInfo mem_alloc = {};
3435 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3436 mem_alloc.pNext = NULL;
3437 mem_alloc.allocationSize = 0;
3438 mem_alloc.memoryTypeIndex = 0;
3440 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3441 ASSERT_VK_SUCCESS(err);
3443 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3445 mem_alloc.allocationSize = mem_reqs.size;
3447 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3451 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3452 ASSERT_VK_SUCCESS(err);
3454 // Introduce validation failure, free memory before binding
3455 vkFreeMemory(m_device->device(), mem, NULL);
3457 // Try to bind free memory that has been freed
3458 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3459 // This may very well return an error.
3462 m_errorMonitor->VerifyFound();
3464 vkDestroyImage(m_device->device(), image, NULL);
3467 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3471 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object ");
3473 ASSERT_NO_FATAL_FAILURE(InitState());
3475 // Create an image object, allocate memory, destroy the object and then try
3479 VkMemoryRequirements mem_reqs;
3481 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3482 const int32_t tex_width = 32;
3483 const int32_t tex_height = 32;
3485 VkImageCreateInfo image_create_info = {};
3486 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3487 image_create_info.pNext = NULL;
3488 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3489 image_create_info.format = tex_format;
3490 image_create_info.extent.width = tex_width;
3491 image_create_info.extent.height = tex_height;
3492 image_create_info.extent.depth = 1;
3493 image_create_info.mipLevels = 1;
3494 image_create_info.arrayLayers = 1;
3495 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3496 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
3497 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3498 image_create_info.flags = 0;
3500 VkMemoryAllocateInfo mem_alloc = {};
3501 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3502 mem_alloc.pNext = NULL;
3503 mem_alloc.allocationSize = 0;
3504 mem_alloc.memoryTypeIndex = 0;
3506 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3507 ASSERT_VK_SUCCESS(err);
3509 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3511 mem_alloc.allocationSize = mem_reqs.size;
3512 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3516 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3517 ASSERT_VK_SUCCESS(err);
3519 // Introduce validation failure, destroy Image object before binding
3520 vkDestroyImage(m_device->device(), image, NULL);
3521 ASSERT_VK_SUCCESS(err);
3523 // Now Try to bind memory to this destroyed object
3524 err = vkBindImageMemory(m_device->device(), image, mem, 0);
3525 // This may very well return an error.
3528 m_errorMonitor->VerifyFound();
3530 vkFreeMemory(m_device->device(), mem, NULL);
3533 #endif // OBJ_TRACKER_TESTS
3535 #if DRAW_STATE_TESTS
3537 TEST_F(VkLayerTest, ImageSampleCounts) {
3539 TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger "
3540 "validation errors.");
3541 ASSERT_NO_FATAL_FAILURE(InitState());
3543 VkMemoryPropertyFlags reqs = 0;
3544 VkImageCreateInfo image_create_info = {};
3545 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3546 image_create_info.pNext = NULL;
3547 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3548 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3549 image_create_info.extent.width = 256;
3550 image_create_info.extent.height = 256;
3551 image_create_info.extent.depth = 1;
3552 image_create_info.mipLevels = 1;
3553 image_create_info.arrayLayers = 1;
3554 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3555 image_create_info.flags = 0;
3557 VkImageBlit blit_region = {};
3558 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3559 blit_region.srcSubresource.baseArrayLayer = 0;
3560 blit_region.srcSubresource.layerCount = 1;
3561 blit_region.srcSubresource.mipLevel = 0;
3562 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3563 blit_region.dstSubresource.baseArrayLayer = 0;
3564 blit_region.dstSubresource.layerCount = 1;
3565 blit_region.dstSubresource.mipLevel = 0;
3567 // Create two images, the source with sampleCount = 2, and attempt to blit
3570 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3571 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3572 vk_testing::Image src_image;
3573 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3574 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3575 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3576 vk_testing::Image dst_image;
3577 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3578 m_commandBuffer->BeginCommandBuffer();
3579 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3580 "of VK_SAMPLE_COUNT_2_BIT but "
3581 "must be VK_SAMPLE_COUNT_1_BIT");
3582 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3583 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3584 m_errorMonitor->VerifyFound();
3585 m_commandBuffer->EndCommandBuffer();
3588 // Create two images, the dest with sampleCount = 4, and attempt to blit
3591 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3592 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3593 vk_testing::Image src_image;
3594 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3595 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3596 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3597 vk_testing::Image dst_image;
3598 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3599 m_commandBuffer->BeginCommandBuffer();
3600 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3601 "of VK_SAMPLE_COUNT_4_BIT but "
3602 "must be VK_SAMPLE_COUNT_1_BIT");
3603 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3604 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3605 m_errorMonitor->VerifyFound();
3606 m_commandBuffer->EndCommandBuffer();
3609 VkBufferImageCopy copy_region = {};
3610 copy_region.bufferRowLength = 128;
3611 copy_region.bufferImageHeight = 128;
3612 copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3613 copy_region.imageSubresource.layerCount = 1;
3614 copy_region.imageExtent.height = 64;
3615 copy_region.imageExtent.width = 64;
3616 copy_region.imageExtent.depth = 1;
3618 // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3621 vk_testing::Buffer src_buffer;
3622 VkMemoryPropertyFlags reqs = 0;
3623 src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3624 image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
3625 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3626 vk_testing::Image dst_image;
3627 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3628 m_commandBuffer->BeginCommandBuffer();
3629 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3630 "of VK_SAMPLE_COUNT_8_BIT but "
3631 "must be VK_SAMPLE_COUNT_1_BIT");
3632 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(),
3633 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region);
3634 m_errorMonitor->VerifyFound();
3635 m_commandBuffer->EndCommandBuffer();
3638 // Create dst buffer and src image with sampleCount = 2 and attempt to copy
3641 vk_testing::Buffer dst_buffer;
3642 dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3643 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3644 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3645 vk_testing::Image src_image;
3646 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3647 m_commandBuffer->BeginCommandBuffer();
3648 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count "
3649 "of VK_SAMPLE_COUNT_2_BIT but "
3650 "must be VK_SAMPLE_COUNT_1_BIT");
3651 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3652 dst_buffer.handle(), 1, ©_region);
3653 m_errorMonitor->VerifyFound();
3654 m_commandBuffer->EndCommandBuffer();
3658 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
3662 TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
3663 ASSERT_NO_FATAL_FAILURE(InitState());
3665 // If w/d/h granularity is 1, test is not meaningful
3666 // TODO: When virtual device limits are available, create a set of limits for this test that
3667 // will always have a granularity of > 1 for w, h, and d
3668 auto index = m_device->graphics_queue_node_index_;
3669 auto queue_family_properties = m_device->phy().queue_properties();
3671 if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
3672 (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
3673 (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
3677 // Create two images of different types and try to copy between them
3680 VkDeviceMemory srcMem;
3681 VkDeviceMemory destMem;
3682 VkMemoryRequirements memReqs;
3684 VkImageCreateInfo image_create_info = {};
3685 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3686 image_create_info.pNext = NULL;
3687 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3688 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3689 image_create_info.extent.width = 32;
3690 image_create_info.extent.height = 32;
3691 image_create_info.extent.depth = 1;
3692 image_create_info.mipLevels = 1;
3693 image_create_info.arrayLayers = 4;
3694 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3695 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3696 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3697 image_create_info.flags = 0;
3699 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
3700 ASSERT_VK_SUCCESS(err);
3702 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
3703 ASSERT_VK_SUCCESS(err);
3706 VkMemoryAllocateInfo memAlloc = {};
3707 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3708 memAlloc.pNext = NULL;
3709 memAlloc.allocationSize = 0;
3710 memAlloc.memoryTypeIndex = 0;
3712 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
3713 memAlloc.allocationSize = memReqs.size;
3714 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3716 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
3717 ASSERT_VK_SUCCESS(err);
3719 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
3720 memAlloc.allocationSize = memReqs.size;
3721 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
3722 ASSERT_VK_SUCCESS(err);
3723 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
3724 ASSERT_VK_SUCCESS(err);
3726 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
3727 ASSERT_VK_SUCCESS(err);
3728 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
3729 ASSERT_VK_SUCCESS(err);
3731 BeginCommandBuffer();
3732 VkImageCopy copyRegion;
3733 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3734 copyRegion.srcSubresource.mipLevel = 0;
3735 copyRegion.srcSubresource.baseArrayLayer = 0;
3736 copyRegion.srcSubresource.layerCount = 1;
3737 copyRegion.srcOffset.x = 0;
3738 copyRegion.srcOffset.y = 0;
3739 copyRegion.srcOffset.z = 0;
3740 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3741 copyRegion.dstSubresource.mipLevel = 0;
3742 copyRegion.dstSubresource.baseArrayLayer = 0;
3743 copyRegion.dstSubresource.layerCount = 1;
3744 copyRegion.dstOffset.x = 0;
3745 copyRegion.dstOffset.y = 0;
3746 copyRegion.dstOffset.z = 0;
3747 copyRegion.extent.width = 1;
3748 copyRegion.extent.height = 1;
3749 copyRegion.extent.depth = 1;
3751 // Introduce failure by setting srcOffset to a bad granularity value
3752 copyRegion.srcOffset.y = 3;
3753 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3754 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
3755 m_errorMonitor->VerifyFound();
3757 // Introduce failure by setting extent to a bad granularity value
3758 copyRegion.srcOffset.y = 0;
3759 copyRegion.extent.width = 3;
3760 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3761 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
3762 m_errorMonitor->VerifyFound();
3764 // Now do some buffer/image copies
3765 vk_testing::Buffer buffer;
3766 VkMemoryPropertyFlags reqs = 0;
3767 buffer.init_as_dst(*m_device, 128 * 128, reqs);
3768 VkBufferImageCopy region = {};
3769 region.bufferOffset = 0;
3770 region.bufferRowLength = 3;
3771 region.bufferImageHeight = 128;
3772 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3773 region.imageSubresource.layerCount = 1;
3774 region.imageExtent.height = 16;
3775 region.imageExtent.width = 16;
3776 region.imageExtent.depth = 1;
3777 region.imageOffset.x = 0;
3778 region.imageOffset.y = 0;
3779 region.imageOffset.z = 0;
3781 // Introduce failure by setting bufferRowLength to a bad granularity value
3782 region.bufferRowLength = 3;
3783 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3784 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3786 m_errorMonitor->VerifyFound();
3787 region.bufferRowLength = 128;
3789 // Introduce failure by setting bufferOffset to a bad granularity value
3790 region.bufferOffset = 3;
3791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3792 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3794 m_errorMonitor->VerifyFound();
3795 region.bufferOffset = 0;
3797 // Introduce failure by setting bufferImageHeight to a bad granularity value
3798 region.bufferImageHeight = 3;
3799 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3800 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3802 m_errorMonitor->VerifyFound();
3803 region.bufferImageHeight = 128;
3805 // Introduce failure by setting imageExtent to a bad granularity value
3806 region.imageExtent.width = 3;
3807 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3808 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1,
3810 m_errorMonitor->VerifyFound();
3811 region.imageExtent.width = 16;
3813 // Introduce failure by setting imageOffset to a bad granularity value
3814 region.imageOffset.z = 3;
3815 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
3816 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3818 m_errorMonitor->VerifyFound();
3822 vkDestroyImage(m_device->device(), srcImage, NULL);
3823 vkDestroyImage(m_device->device(), dstImage, NULL);
3824 vkFreeMemory(m_device->device(), srcMem, NULL);
3825 vkFreeMemory(m_device->device(), destMem, NULL);
3828 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
3829 TEST_DESCRIPTION("Submit command buffer created using one queue family and "
3830 "attempt to submit them on a queue created in a different "
3833 ASSERT_NO_FATAL_FAILURE(InitState());
3834 // This test is meaningless unless we have multiple queue families
3835 auto queue_family_properties = m_device->phy().queue_properties();
3836 if (queue_family_properties.size() < 2) {
3839 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue ");
3840 // Get safe index of another queue family
3841 uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
3842 ASSERT_NO_FATAL_FAILURE(InitState());
3843 // Create a second queue using a different queue family
3844 VkQueue other_queue;
3845 vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
3847 // Record an empty cmd buffer
3848 VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3849 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3850 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
3851 vkEndCommandBuffer(m_commandBuffer->handle());
3853 // And submit on the wrong queue
3854 VkSubmitInfo submit_info = {};
3855 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3856 submit_info.commandBufferCount = 1;
3857 submit_info.pCommandBuffers = &m_commandBuffer->handle();
3858 vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
3860 m_errorMonitor->VerifyFound();
3863 TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
3864 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
3865 "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
3866 "the command buffer has prior knowledge of that "
3867 "attachment's layout.");
3869 m_errorMonitor->ExpectSuccess();
3871 ASSERT_NO_FATAL_FAILURE(InitState());
3873 // A renderpass with one color attachment.
3874 VkAttachmentDescription attachment = {0,
3875 VK_FORMAT_R8G8B8A8_UNORM,
3876 VK_SAMPLE_COUNT_1_BIT,
3877 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3878 VK_ATTACHMENT_STORE_OP_STORE,
3879 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3880 VK_ATTACHMENT_STORE_OP_DONT_CARE,
3881 VK_IMAGE_LAYOUT_UNDEFINED,
3882 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3884 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3886 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3888 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3891 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3892 ASSERT_VK_SUCCESS(err);
3894 // A compatible framebuffer.
3895 VkImageObj image(m_device);
3896 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3897 ASSERT_TRUE(image.initialized());
3899 VkImageViewCreateInfo ivci = {
3900 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3904 VK_IMAGE_VIEW_TYPE_2D,
3905 VK_FORMAT_R8G8B8A8_UNORM,
3906 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3907 VK_COMPONENT_SWIZZLE_IDENTITY},
3908 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3911 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3912 ASSERT_VK_SUCCESS(err);
3914 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3916 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3917 ASSERT_VK_SUCCESS(err);
3919 // Record a single command buffer which uses this renderpass twice. The
3920 // bug is triggered at the beginning of the second renderpass, when the
3921 // command buffer already has a layout recorded for the attachment.
3922 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3923 BeginCommandBuffer();
3924 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3925 vkCmdEndRenderPass(m_commandBuffer->handle());
3926 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3928 m_errorMonitor->VerifyNotFound();
3930 vkCmdEndRenderPass(m_commandBuffer->handle());
3933 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3934 vkDestroyRenderPass(m_device->device(), rp, nullptr);
3935 vkDestroyImageView(m_device->device(), view, nullptr);
3938 TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
3939 TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
3940 "command buffer, bind them together, then destroy "
3941 "command pool and framebuffer and verify there are no "
3944 m_errorMonitor->ExpectSuccess();
3946 ASSERT_NO_FATAL_FAILURE(InitState());
3948 // A renderpass with one color attachment.
3949 VkAttachmentDescription attachment = {0,
3950 VK_FORMAT_R8G8B8A8_UNORM,
3951 VK_SAMPLE_COUNT_1_BIT,
3952 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3953 VK_ATTACHMENT_STORE_OP_STORE,
3954 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3955 VK_ATTACHMENT_STORE_OP_DONT_CARE,
3956 VK_IMAGE_LAYOUT_UNDEFINED,
3957 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3959 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3961 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3963 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3966 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3967 ASSERT_VK_SUCCESS(err);
3969 // A compatible framebuffer.
3970 VkImageObj image(m_device);
3971 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3972 ASSERT_TRUE(image.initialized());
3974 VkImageViewCreateInfo ivci = {
3975 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3979 VK_IMAGE_VIEW_TYPE_2D,
3980 VK_FORMAT_R8G8B8A8_UNORM,
3981 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
3982 VK_COMPONENT_SWIZZLE_IDENTITY},
3983 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
3986 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
3987 ASSERT_VK_SUCCESS(err);
3989 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3991 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3992 ASSERT_VK_SUCCESS(err);
3994 // Explicitly create a command buffer to bind the FB to so that we can then
3995 // destroy the command pool in order to implicitly free command buffer
3996 VkCommandPool command_pool;
3997 VkCommandPoolCreateInfo pool_create_info{};
3998 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3999 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4000 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4001 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4003 VkCommandBuffer command_buffer;
4004 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4005 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4006 command_buffer_allocate_info.commandPool = command_pool;
4007 command_buffer_allocate_info.commandBufferCount = 1;
4008 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4009 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4011 // Begin our cmd buffer with renderpass using our framebuffer
4012 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4013 VkCommandBufferBeginInfo begin_info{};
4014 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4015 vkBeginCommandBuffer(command_buffer, &begin_info);
4017 vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4018 vkCmdEndRenderPass(command_buffer);
4019 vkEndCommandBuffer(command_buffer);
4020 vkDestroyImageView(m_device->device(), view, nullptr);
4021 // Destroy command pool to implicitly free command buffer
4022 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4023 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4024 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4025 m_errorMonitor->VerifyNotFound();
4028 TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
4029 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
4030 "transitions for the first subpass");
4032 m_errorMonitor->ExpectSuccess();
4034 ASSERT_NO_FATAL_FAILURE(InitState());
4036 // A renderpass with one color attachment.
4037 VkAttachmentDescription attachment = {0,
4038 VK_FORMAT_R8G8B8A8_UNORM,
4039 VK_SAMPLE_COUNT_1_BIT,
4040 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4041 VK_ATTACHMENT_STORE_OP_STORE,
4042 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4043 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4044 VK_IMAGE_LAYOUT_UNDEFINED,
4045 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4047 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4049 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4051 VkSubpassDependency dep = {0,
4053 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4054 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4055 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4056 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4057 VK_DEPENDENCY_BY_REGION_BIT};
4059 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4063 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4064 ASSERT_VK_SUCCESS(err);
4066 // A compatible framebuffer.
4067 VkImageObj image(m_device);
4068 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4069 ASSERT_TRUE(image.initialized());
4071 VkImageViewCreateInfo ivci = {
4072 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4076 VK_IMAGE_VIEW_TYPE_2D,
4077 VK_FORMAT_R8G8B8A8_UNORM,
4078 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
4079 VK_COMPONENT_SWIZZLE_IDENTITY},
4080 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
4083 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4084 ASSERT_VK_SUCCESS(err);
4086 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4088 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4089 ASSERT_VK_SUCCESS(err);
4091 // Record a single command buffer which issues a pipeline barrier w/
4092 // image memory barrier for the attachment. This detects the previously
4093 // missing tracking of the subpass layout by throwing a validation error
4094 // if it doesn't occur.
4095 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4096 BeginCommandBuffer();
4097 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4099 VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4101 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4102 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4103 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4104 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4105 VK_QUEUE_FAMILY_IGNORED,
4106 VK_QUEUE_FAMILY_IGNORED,
4108 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
4109 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4110 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4113 vkCmdEndRenderPass(m_commandBuffer->handle());
4114 m_errorMonitor->VerifyNotFound();
4117 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4118 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4119 vkDestroyImageView(m_device->device(), view, nullptr);
4122 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
4123 TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4124 ASSERT_NO_FATAL_FAILURE(InitState());
4126 // A renderpass with two subpasses, both writing the same attachment.
4127 VkAttachmentDescription attach[] = {
4128 { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
4129 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4130 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4131 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4134 VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
4135 VkSubpassDescription subpasses[] = {
4136 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4137 1, &ref, nullptr, nullptr, 0, nullptr },
4138 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
4139 1, &ref, nullptr, nullptr, 0, nullptr },
4141 VkSubpassDependency dep = {
4143 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4144 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4145 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4146 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4147 VK_DEPENDENCY_BY_REGION_BIT
4149 VkRenderPassCreateInfo rpci = {
4150 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
4151 0, 1, attach, 2, subpasses, 1, &dep
4154 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4155 ASSERT_VK_SUCCESS(err);
4157 VkImageObj image(m_device);
4158 image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
4159 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4160 VK_IMAGE_TILING_OPTIMAL, 0);
4161 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4163 VkFramebufferCreateInfo fbci = {
4164 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
4165 0, rp, 1, &imageView, 32, 32, 1
4168 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4169 ASSERT_VK_SUCCESS(err);
4171 char const *vsSource =
4173 "void main() { gl_Position = vec4(1); }\n";
4174 char const *fsSource =
4176 "layout(location=0) out vec4 color;\n"
4177 "void main() { color = vec4(1); }\n";
4179 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4180 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4181 VkPipelineObj pipe(m_device);
4182 pipe.AddColorAttachment();
4183 pipe.AddShader(&vs);
4184 pipe.AddShader(&fs);
4185 VkViewport view_port = {};
4186 m_viewports.push_back(view_port);
4187 pipe.SetViewport(m_viewports);
4189 m_scissors.push_back(rect);
4190 pipe.SetScissor(m_scissors);
4192 VkPipelineLayoutCreateInfo plci = {
4193 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
4194 0, 0, nullptr, 0, nullptr
4196 VkPipelineLayout pl;
4197 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
4198 ASSERT_VK_SUCCESS(err);
4199 pipe.CreateVKPipeline(pl, rp);
4201 BeginCommandBuffer();
4203 VkRenderPassBeginInfo rpbi = {
4204 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
4205 rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
4208 // subtest 1: bind in the wrong subpass
4209 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4210 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4211 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4212 "built for subpass 0 but used in subpass 1");
4213 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4214 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4215 m_errorMonitor->VerifyFound();
4217 vkCmdEndRenderPass(m_commandBuffer->handle());
4219 // subtest 2: bind in correct subpass, then transition to next subpass
4220 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4221 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4222 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4223 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4224 "built for subpass 0 but used in subpass 1");
4225 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4226 m_errorMonitor->VerifyFound();
4228 vkCmdEndRenderPass(m_commandBuffer->handle());
4232 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
4233 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4234 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4237 TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
4238 TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
4239 "is used as a depth/stencil framebuffer attachment, the "
4240 "aspectMask is ignored and both depth and stencil image "
4241 "subresources are used.");
4243 VkFormatProperties format_properties;
4244 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
4245 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
4249 m_errorMonitor->ExpectSuccess();
4251 ASSERT_NO_FATAL_FAILURE(InitState());
4253 VkAttachmentDescription attachment = {0,
4254 VK_FORMAT_D32_SFLOAT_S8_UINT,
4255 VK_SAMPLE_COUNT_1_BIT,
4256 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4257 VK_ATTACHMENT_STORE_OP_STORE,
4258 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4259 VK_ATTACHMENT_STORE_OP_DONT_CARE,
4260 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4261 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4263 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
4265 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
4267 VkSubpassDependency dep = {0,
4269 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4270 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4271 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4272 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4273 VK_DEPENDENCY_BY_REGION_BIT};
4275 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
4279 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4280 ASSERT_VK_SUCCESS(err);
4282 VkImageObj image(m_device);
4283 image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
4285 VK_IMAGE_TILING_OPTIMAL, 0);
4286 ASSERT_TRUE(image.initialized());
4287 image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
4289 VkImageViewCreateInfo ivci = {
4290 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4294 VK_IMAGE_VIEW_TYPE_2D,
4295 VK_FORMAT_D32_SFLOAT_S8_UINT,
4296 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
4300 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
4301 ASSERT_VK_SUCCESS(err);
4303 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
4305 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4306 ASSERT_VK_SUCCESS(err);
4308 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4309 BeginCommandBuffer();
4310 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4312 VkImageMemoryBarrier imb = {};
4313 imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4314 imb.pNext = nullptr;
4315 imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4316 imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4317 imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4318 imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4319 imb.srcQueueFamilyIndex = 0;
4320 imb.dstQueueFamilyIndex = 0;
4321 imb.image = image.handle();
4322 imb.subresourceRange.aspectMask = 0x6;
4323 imb.subresourceRange.baseMipLevel = 0;
4324 imb.subresourceRange.levelCount = 0x1;
4325 imb.subresourceRange.baseArrayLayer = 0;
4326 imb.subresourceRange.layerCount = 0x1;
4328 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4329 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
4332 vkCmdEndRenderPass(m_commandBuffer->handle());
4334 QueueCommandBuffer(false);
4335 m_errorMonitor->VerifyNotFound();
4337 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4338 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4339 vkDestroyImageView(m_device->device(), view, nullptr);
4342 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
4343 TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass"
4344 "with extent outside of framebuffer");
4345 ASSERT_NO_FATAL_FAILURE(InitState());
4346 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4348 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea "
4349 "not within the bound of the framebuffer.");
4351 // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
4352 m_renderPassBeginInfo.renderArea.extent.width = 257;
4353 m_renderPassBeginInfo.renderArea.extent.height = 257;
4354 BeginCommandBuffer();
4355 m_errorMonitor->VerifyFound();
4358 TEST_F(VkLayerTest, DisabledIndependentBlend) {
4359 TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent "
4360 "blend and then specifying different blend states for two "
4362 VkPhysicalDeviceFeatures features = {};
4363 features.independentBlend = VK_FALSE;
4364 ASSERT_NO_FATAL_FAILURE(InitState(&features));
4366 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4367 "Invalid Pipeline CreateInfo: If independent blend feature not "
4368 "enabled, all elements of pAttachments must be identical");
4370 VkDescriptorSetObj descriptorSet(m_device);
4371 descriptorSet.AppendDummy();
4372 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
4374 VkPipelineObj pipeline(m_device);
4375 VkRenderpassObj renderpass(m_device);
4376 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4377 pipeline.AddShader(&vs);
4379 VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
4380 att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4381 att_state1.blendEnable = VK_TRUE;
4382 att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
4383 att_state2.blendEnable = VK_FALSE;
4384 pipeline.AddColorAttachment(0, &att_state1);
4385 pipeline.AddColorAttachment(1, &att_state2);
4386 pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle());
4387 m_errorMonitor->VerifyFound();
4390 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) {
4391 TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify "
4392 "depth attachments in subpass");
4393 ASSERT_NO_FATAL_FAILURE(InitState());
4395 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4396 "vkCreateRenderPass has no depth/stencil attachment, yet subpass");
4398 // Create a renderPass with a single color attachment
4399 VkAttachmentReference attach = {};
4400 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4401 VkSubpassDescription subpass = {};
4402 VkRenderPassCreateInfo rpci = {};
4403 rpci.subpassCount = 1;
4404 rpci.pSubpasses = &subpass;
4405 rpci.attachmentCount = 1;
4406 VkAttachmentDescription attach_desc = {};
4407 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4408 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4409 rpci.pAttachments = &attach_desc;
4410 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4412 subpass.pDepthStencilAttachment = &attach;
4413 subpass.pColorAttachments = NULL;
4414 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4415 m_errorMonitor->VerifyFound();
4418 TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
4419 TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
4420 "errors, when an attachment reference is "
4421 "VK_ATTACHMENT_UNUSED");
4423 m_errorMonitor->ExpectSuccess();
4425 ASSERT_NO_FATAL_FAILURE(InitState());
4427 // A renderpass with no attachments
4428 VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4430 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
4432 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
4435 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4436 ASSERT_VK_SUCCESS(err);
4438 // A compatible framebuffer.
4439 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
4441 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
4442 ASSERT_VK_SUCCESS(err);
4444 // Record a command buffer which just begins and ends the renderpass. The
4445 // bug manifests in BeginRenderPass.
4446 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
4447 BeginCommandBuffer();
4448 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4449 vkCmdEndRenderPass(m_commandBuffer->handle());
4450 m_errorMonitor->VerifyNotFound();
4453 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4454 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4457 // This is a positive test. No errors are expected.
4458 TEST_F(VkLayerTest, StencilLoadOp) {
4459 TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
4460 "CLEAR. stencil[Load|Store]Op used to be ignored.");
4461 VkResult result = VK_SUCCESS;
4462 VkImageFormatProperties formatProps;
4463 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
4464 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
4466 if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
4470 ASSERT_NO_FATAL_FAILURE(InitState());
4471 VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
4472 m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
4473 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4474 VkAttachmentDescription att = {};
4475 VkAttachmentReference ref = {};
4476 att.format = depth_stencil_fmt;
4477 att.samples = VK_SAMPLE_COUNT_1_BIT;
4478 att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
4479 att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
4480 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
4481 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
4482 att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4483 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4486 clear.depthStencil.depth = 1.0;
4487 clear.depthStencil.stencil = 0;
4489 ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4491 VkSubpassDescription subpass = {};
4492 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4494 subpass.inputAttachmentCount = 0;
4495 subpass.pInputAttachments = NULL;
4496 subpass.colorAttachmentCount = 0;
4497 subpass.pColorAttachments = NULL;
4498 subpass.pResolveAttachments = NULL;
4499 subpass.pDepthStencilAttachment = &ref;
4500 subpass.preserveAttachmentCount = 0;
4501 subpass.pPreserveAttachments = NULL;
4504 VkRenderPassCreateInfo rp_info = {};
4505 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4506 rp_info.attachmentCount = 1;
4507 rp_info.pAttachments = &att;
4508 rp_info.subpassCount = 1;
4509 rp_info.pSubpasses = &subpass;
4510 result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
4511 ASSERT_VK_SUCCESS(result);
4513 VkImageView *depthView = m_depthStencil->BindInfo();
4514 VkFramebufferCreateInfo fb_info = {};
4515 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4516 fb_info.pNext = NULL;
4517 fb_info.renderPass = rp;
4518 fb_info.attachmentCount = 1;
4519 fb_info.pAttachments = depthView;
4520 fb_info.width = 100;
4521 fb_info.height = 100;
4524 result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4525 ASSERT_VK_SUCCESS(result);
4527 VkRenderPassBeginInfo rpbinfo = {};
4528 rpbinfo.clearValueCount = 1;
4529 rpbinfo.pClearValues = &clear;
4530 rpbinfo.pNext = NULL;
4531 rpbinfo.renderPass = rp;
4532 rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4533 rpbinfo.renderArea.extent.width = 100;
4534 rpbinfo.renderArea.extent.height = 100;
4535 rpbinfo.renderArea.offset.x = 0;
4536 rpbinfo.renderArea.offset.y = 0;
4537 rpbinfo.framebuffer = fb;
4540 VkFenceCreateInfo fence_ci = {};
4541 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4542 fence_ci.pNext = nullptr;
4544 result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
4545 ASSERT_VK_SUCCESS(result);
4547 m_commandBuffer->BeginCommandBuffer();
4548 m_commandBuffer->BeginRenderPass(rpbinfo);
4549 m_commandBuffer->EndRenderPass();
4550 m_commandBuffer->EndCommandBuffer();
4551 m_commandBuffer->QueueCommandBuffer(fence);
4553 VkImageObj destImage(m_device);
4554 destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4555 VK_IMAGE_TILING_OPTIMAL, 0);
4556 VkImageMemoryBarrier barrier = {};
4557 VkImageSubresourceRange range;
4558 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4559 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4560 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4561 barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4562 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4563 barrier.image = m_depthStencil->handle();
4564 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4565 range.baseMipLevel = 0;
4566 range.levelCount = 1;
4567 range.baseArrayLayer = 0;
4568 range.layerCount = 1;
4569 barrier.subresourceRange = range;
4570 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4571 VkCommandBufferObj cmdbuf(m_device, m_commandPool);
4572 cmdbuf.BeginCommandBuffer();
4573 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4575 barrier.srcAccessMask = 0;
4576 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4577 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4578 barrier.image = destImage.handle();
4579 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4580 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
4582 VkImageCopy cregion;
4583 cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4584 cregion.srcSubresource.mipLevel = 0;
4585 cregion.srcSubresource.baseArrayLayer = 0;
4586 cregion.srcSubresource.layerCount = 1;
4587 cregion.srcOffset.x = 0;
4588 cregion.srcOffset.y = 0;
4589 cregion.srcOffset.z = 0;
4590 cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4591 cregion.dstSubresource.mipLevel = 0;
4592 cregion.dstSubresource.baseArrayLayer = 0;
4593 cregion.dstSubresource.layerCount = 1;
4594 cregion.dstOffset.x = 0;
4595 cregion.dstOffset.y = 0;
4596 cregion.dstOffset.z = 0;
4597 cregion.extent.width = 100;
4598 cregion.extent.height = 100;
4599 cregion.extent.depth = 1;
4600 cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
4601 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
4602 cmdbuf.EndCommandBuffer();
4604 VkSubmitInfo submit_info;
4605 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4606 submit_info.pNext = NULL;
4607 submit_info.waitSemaphoreCount = 0;
4608 submit_info.pWaitSemaphores = NULL;
4609 submit_info.pWaitDstStageMask = NULL;
4610 submit_info.commandBufferCount = 1;
4611 submit_info.pCommandBuffers = &cmdbuf.handle();
4612 submit_info.signalSemaphoreCount = 0;
4613 submit_info.pSignalSemaphores = NULL;
4615 m_errorMonitor->ExpectSuccess();
4616 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4617 m_errorMonitor->VerifyNotFound();
4619 vkQueueWaitIdle(m_device->m_queue);
4620 vkDestroyFence(m_device->device(), fence, nullptr);
4621 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4622 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4625 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
4626 TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
4627 "attachment reference of VK_ATTACHMENT_UNUSED");
4629 ASSERT_NO_FATAL_FAILURE(InitState());
4630 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4632 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED");
4634 VkAttachmentReference color_attach = {};
4635 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4636 color_attach.attachment = 0;
4637 uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
4638 VkSubpassDescription subpass = {};
4639 subpass.colorAttachmentCount = 1;
4640 subpass.pColorAttachments = &color_attach;
4641 subpass.preserveAttachmentCount = 1;
4642 subpass.pPreserveAttachments = &preserve_attachment;
4644 VkRenderPassCreateInfo rpci = {};
4645 rpci.subpassCount = 1;
4646 rpci.pSubpasses = &subpass;
4647 rpci.attachmentCount = 1;
4648 VkAttachmentDescription attach_desc = {};
4649 attach_desc.format = VK_FORMAT_UNDEFINED;
4650 rpci.pAttachments = &attach_desc;
4651 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4653 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4655 m_errorMonitor->VerifyFound();
4657 if (result == VK_SUCCESS) {
4658 vkDestroyRenderPass(m_device->device(), rp, NULL);
4662 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
4663 TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
4664 "when the source of a subpass multisample resolve "
4665 "does not have multiple samples.");
4667 ASSERT_NO_FATAL_FAILURE(InitState());
4669 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4670 "Subpass 0 requests multisample resolve from attachment 0 which has "
4671 "VK_SAMPLE_COUNT_1_BIT");
4673 VkAttachmentDescription attachments[] = {
4674 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4675 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4676 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4677 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4678 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4679 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4682 VkAttachmentReference color = {
4683 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4686 VkAttachmentReference resolve = {
4687 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4690 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4692 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4695 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4697 m_errorMonitor->VerifyFound();
4699 if (err == VK_SUCCESS)
4700 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4703 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
4704 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4705 "when a subpass multisample resolve operation is "
4706 "requested, and the destination of that resolve has "
4707 "multiple samples.");
4709 ASSERT_NO_FATAL_FAILURE(InitState());
4711 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4712 "Subpass 0 requests multisample resolve into attachment 1, which "
4713 "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
4715 VkAttachmentDescription attachments[] = {
4716 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4717 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4718 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4719 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4720 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4721 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4724 VkAttachmentReference color = {
4725 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4728 VkAttachmentReference resolve = {
4729 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4732 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr};
4734 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4737 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4739 m_errorMonitor->VerifyFound();
4741 if (err == VK_SUCCESS)
4742 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4745 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
4746 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
4747 "when the color and depth attachments used by a subpass "
4748 "have inconsistent sample counts");
4750 ASSERT_NO_FATAL_FAILURE(InitState());
4752 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4753 "Subpass 0 attempts to render to attachments with inconsistent sample counts");
4755 VkAttachmentDescription attachments[] = {
4756 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4757 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4758 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4759 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4760 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4761 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4764 VkAttachmentReference color[] = {
4766 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4769 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4773 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr};
4775 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
4778 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4780 m_errorMonitor->VerifyFound();
4782 if (err == VK_SUCCESS)
4783 vkDestroyRenderPass(m_device->device(), rp, nullptr);
4786 TEST_F(VkLayerTest, FramebufferCreateErrors) {
4787 TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
4788 " 1. Mismatch between fb & renderPass attachmentCount\n"
4789 " 2. Use a color image as depthStencil attachment\n"
4790 " 3. Mismatch fb & renderPass attachment formats\n"
4791 " 4. Mismatch fb & renderPass attachment #samples\n"
4792 " 5. FB attachment w/ non-1 mip-levels\n"
4793 " 6. FB attachment where dimensions don't match\n"
4794 " 7. FB attachment w/o identity swizzle\n"
4795 " 8. FB dimensions exceed physical device limits\n");
4797 ASSERT_NO_FATAL_FAILURE(InitState());
4798 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4800 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4801 "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
4802 "does not match attachmentCount of 1 of ");
4804 // Create a renderPass with a single color attachment
4805 VkAttachmentReference attach = {};
4806 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
4807 VkSubpassDescription subpass = {};
4808 subpass.pColorAttachments = &attach;
4809 VkRenderPassCreateInfo rpci = {};
4810 rpci.subpassCount = 1;
4811 rpci.pSubpasses = &subpass;
4812 rpci.attachmentCount = 1;
4813 VkAttachmentDescription attach_desc = {};
4814 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4815 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4816 rpci.pAttachments = &attach_desc;
4817 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
4819 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4820 ASSERT_VK_SUCCESS(err);
4823 ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4824 ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
4825 VkFramebufferCreateInfo fb_info = {};
4826 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
4827 fb_info.pNext = NULL;
4828 fb_info.renderPass = rp;
4829 // Set mis-matching attachmentCount
4830 fb_info.attachmentCount = 2;
4831 fb_info.pAttachments = ivs;
4832 fb_info.width = 100;
4833 fb_info.height = 100;
4837 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4839 m_errorMonitor->VerifyFound();
4840 if (err == VK_SUCCESS) {
4841 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4843 vkDestroyRenderPass(m_device->device(), rp, NULL);
4845 // Create a renderPass with a depth-stencil attachment created with
4846 // IMAGE_USAGE_COLOR_ATTACHMENT
4847 // Add our color attachment to pDepthStencilAttachment
4848 subpass.pDepthStencilAttachment = &attach;
4849 subpass.pColorAttachments = NULL;
4851 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
4852 ASSERT_VK_SUCCESS(err);
4853 // Set correct attachment count, but attachment has COLOR usage bit set
4854 fb_info.attachmentCount = 1;
4855 fb_info.renderPass = rp_ds;
4857 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags ");
4858 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4860 m_errorMonitor->VerifyFound();
4861 if (err == VK_SUCCESS) {
4862 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4864 vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
4866 // Create new renderpass with alternate attachment format from fb
4867 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
4868 subpass.pDepthStencilAttachment = NULL;
4869 subpass.pColorAttachments = &attach;
4870 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4871 ASSERT_VK_SUCCESS(err);
4873 // Cause error due to mis-matched formats between rp & fb
4874 // rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
4875 fb_info.renderPass = rp;
4876 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4877 " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
4878 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4880 m_errorMonitor->VerifyFound();
4881 if (err == VK_SUCCESS) {
4882 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4884 vkDestroyRenderPass(m_device->device(), rp, NULL);
4886 // Create new renderpass with alternate sample count from fb
4887 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
4888 attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
4889 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4890 ASSERT_VK_SUCCESS(err);
4892 // Cause error due to mis-matched sample count between rp & fb
4893 fb_info.renderPass = rp;
4894 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples "
4895 "that do not match the "
4896 "VK_SAMPLE_COUNT_4_BIT ");
4897 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4899 m_errorMonitor->VerifyFound();
4900 if (err == VK_SUCCESS) {
4901 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4904 vkDestroyRenderPass(m_device->device(), rp, NULL);
4906 // Create a custom imageView with non-1 mip levels
4907 VkImageObj image(m_device);
4908 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4909 ASSERT_TRUE(image.initialized());
4912 VkImageViewCreateInfo ivci = {};
4913 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4914 ivci.image = image.handle();
4915 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4916 ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4917 ivci.subresourceRange.layerCount = 1;
4918 ivci.subresourceRange.baseMipLevel = 0;
4919 // Set level count 2 (only 1 is allowed for FB attachment)
4920 ivci.subresourceRange.levelCount = 2;
4921 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4922 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4923 ASSERT_VK_SUCCESS(err);
4924 // Re-create renderpass to have matching sample count
4925 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
4926 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
4927 ASSERT_VK_SUCCESS(err);
4929 fb_info.renderPass = rp;
4930 fb_info.pAttachments = &view;
4931 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only ");
4932 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4934 m_errorMonitor->VerifyFound();
4935 if (err == VK_SUCCESS) {
4936 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4938 vkDestroyImageView(m_device->device(), view, NULL);
4939 // Update view to original color buffer and grow FB dimensions too big
4940 fb_info.pAttachments = ivs;
4941 fb_info.height = 1024;
4942 fb_info.width = 1024;
4944 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at "
4945 "least as large. ");
4946 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4948 m_errorMonitor->VerifyFound();
4949 if (err == VK_SUCCESS) {
4950 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4952 // Create view attachment with non-identity swizzle
4953 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4954 ivci.image = image.handle();
4955 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4956 ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
4957 ivci.subresourceRange.layerCount = 1;
4958 ivci.subresourceRange.baseMipLevel = 0;
4959 ivci.subresourceRange.levelCount = 1;
4960 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4961 ivci.components.r = VK_COMPONENT_SWIZZLE_G;
4962 ivci.components.g = VK_COMPONENT_SWIZZLE_R;
4963 ivci.components.b = VK_COMPONENT_SWIZZLE_A;
4964 ivci.components.a = VK_COMPONENT_SWIZZLE_B;
4965 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
4966 ASSERT_VK_SUCCESS(err);
4968 fb_info.pAttachments = &view;
4969 fb_info.height = 100;
4970 fb_info.width = 100;
4972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All "
4973 "framebuffer attachments must have "
4974 "been created with the identity "
4976 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4978 m_errorMonitor->VerifyFound();
4979 if (err == VK_SUCCESS) {
4980 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4982 vkDestroyImageView(m_device->device(), view, NULL);
4983 // Request fb that exceeds max dimensions
4984 // reset attachment to color attachment
4985 fb_info.pAttachments = ivs;
4986 fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
4987 fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
4988 fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
4989 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo "
4990 "dimensions exceed physical device "
4992 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
4994 m_errorMonitor->VerifyFound();
4995 if (err == VK_SUCCESS) {
4996 vkDestroyFramebuffer(m_device->device(), fb, NULL);
4999 vkDestroyRenderPass(m_device->device(), rp, NULL);
5002 // This is a positive test. No errors should be generated.
5003 TEST_F(VkLayerTest, WaitEventThenSet) {
5004 TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
5006 m_errorMonitor->ExpectSuccess();
5007 ASSERT_NO_FATAL_FAILURE(InitState());
5010 VkEventCreateInfo event_create_info{};
5011 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5012 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5014 VkCommandPool command_pool;
5015 VkCommandPoolCreateInfo pool_create_info{};
5016 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5017 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5018 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5019 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5021 VkCommandBuffer command_buffer;
5022 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5023 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5024 command_buffer_allocate_info.commandPool = command_pool;
5025 command_buffer_allocate_info.commandBufferCount = 1;
5026 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5027 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5029 VkQueue queue = VK_NULL_HANDLE;
5030 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5033 VkCommandBufferBeginInfo begin_info{};
5034 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5035 vkBeginCommandBuffer(command_buffer, &begin_info);
5037 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
5038 nullptr, 0, nullptr);
5039 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5040 vkEndCommandBuffer(command_buffer);
5043 VkSubmitInfo submit_info{};
5044 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5045 submit_info.commandBufferCount = 1;
5046 submit_info.pCommandBuffers = &command_buffer;
5047 submit_info.signalSemaphoreCount = 0;
5048 submit_info.pSignalSemaphores = nullptr;
5049 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5051 { vkSetEvent(m_device->device(), event); }
5053 vkQueueWaitIdle(queue);
5055 vkDestroyEvent(m_device->device(), event, nullptr);
5056 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5057 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5059 m_errorMonitor->VerifyNotFound();
5061 // This is a positive test. No errors should be generated.
5062 TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
5063 TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
5065 ASSERT_NO_FATAL_FAILURE(InitState());
5066 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5069 m_errorMonitor->ExpectSuccess();
5071 VkQueryPool query_pool;
5072 VkQueryPoolCreateInfo query_pool_create_info{};
5073 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5074 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5075 query_pool_create_info.queryCount = 1;
5076 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5078 VkCommandPool command_pool;
5079 VkCommandPoolCreateInfo pool_create_info{};
5080 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5081 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5082 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5083 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5085 VkCommandBuffer command_buffer;
5086 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5087 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5088 command_buffer_allocate_info.commandPool = command_pool;
5089 command_buffer_allocate_info.commandBufferCount = 1;
5090 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5091 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5093 VkCommandBuffer secondary_command_buffer;
5094 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5095 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
5097 VkQueue queue = VK_NULL_HANDLE;
5098 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5101 VkBufferCreateInfo buff_create_info = {};
5102 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5103 buff_create_info.size = 1024;
5104 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5105 buff_create_info.queueFamilyIndexCount = 1;
5106 buff_create_info.pQueueFamilyIndices = &qfi;
5110 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5111 ASSERT_VK_SUCCESS(err);
5112 VkMemoryAllocateInfo mem_alloc = {};
5113 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5114 mem_alloc.pNext = NULL;
5115 mem_alloc.allocationSize = 1024;
5116 mem_alloc.memoryTypeIndex = 0;
5118 VkMemoryRequirements memReqs;
5119 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5120 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5122 vkDestroyBuffer(m_device->device(), buffer, NULL);
5127 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5128 ASSERT_VK_SUCCESS(err);
5129 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5130 ASSERT_VK_SUCCESS(err);
5132 VkCommandBufferInheritanceInfo hinfo = {};
5133 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5134 hinfo.renderPass = VK_NULL_HANDLE;
5136 hinfo.framebuffer = VK_NULL_HANDLE;
5137 hinfo.occlusionQueryEnable = VK_FALSE;
5138 hinfo.queryFlags = 0;
5139 hinfo.pipelineStatistics = 0;
5142 VkCommandBufferBeginInfo begin_info{};
5143 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5144 begin_info.pInheritanceInfo = &hinfo;
5145 vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
5147 vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
5148 vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5150 vkEndCommandBuffer(secondary_command_buffer);
5152 begin_info.pInheritanceInfo = nullptr;
5153 vkBeginCommandBuffer(command_buffer, &begin_info);
5155 vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
5156 vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
5158 vkEndCommandBuffer(command_buffer);
5161 VkSubmitInfo submit_info{};
5162 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5163 submit_info.commandBufferCount = 1;
5164 submit_info.pCommandBuffers = &command_buffer;
5165 submit_info.signalSemaphoreCount = 0;
5166 submit_info.pSignalSemaphores = nullptr;
5167 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5170 vkQueueWaitIdle(queue);
5172 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5173 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5174 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
5175 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5176 vkDestroyBuffer(m_device->device(), buffer, NULL);
5177 vkFreeMemory(m_device->device(), mem, NULL);
5179 m_errorMonitor->VerifyNotFound();
5182 // This is a positive test. No errors should be generated.
5183 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
5184 TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
5186 ASSERT_NO_FATAL_FAILURE(InitState());
5187 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5190 m_errorMonitor->ExpectSuccess();
5192 VkQueryPool query_pool;
5193 VkQueryPoolCreateInfo query_pool_create_info{};
5194 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5195 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5196 query_pool_create_info.queryCount = 1;
5197 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
5199 VkCommandPool command_pool;
5200 VkCommandPoolCreateInfo pool_create_info{};
5201 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5202 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5203 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5204 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5206 VkCommandBuffer command_buffer[2];
5207 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5208 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5209 command_buffer_allocate_info.commandPool = command_pool;
5210 command_buffer_allocate_info.commandBufferCount = 2;
5211 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5212 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5214 VkQueue queue = VK_NULL_HANDLE;
5215 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5218 VkBufferCreateInfo buff_create_info = {};
5219 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5220 buff_create_info.size = 1024;
5221 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5222 buff_create_info.queueFamilyIndexCount = 1;
5223 buff_create_info.pQueueFamilyIndices = &qfi;
5227 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
5228 ASSERT_VK_SUCCESS(err);
5229 VkMemoryAllocateInfo mem_alloc = {};
5230 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5231 mem_alloc.pNext = NULL;
5232 mem_alloc.allocationSize = 1024;
5233 mem_alloc.memoryTypeIndex = 0;
5235 VkMemoryRequirements memReqs;
5236 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
5237 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
5239 vkDestroyBuffer(m_device->device(), buffer, NULL);
5244 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
5245 ASSERT_VK_SUCCESS(err);
5246 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
5247 ASSERT_VK_SUCCESS(err);
5250 VkCommandBufferBeginInfo begin_info{};
5251 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5252 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5254 vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
5255 vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
5257 vkEndCommandBuffer(command_buffer[0]);
5259 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5261 vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
5263 vkEndCommandBuffer(command_buffer[1]);
5266 VkSubmitInfo submit_info{};
5267 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5268 submit_info.commandBufferCount = 2;
5269 submit_info.pCommandBuffers = command_buffer;
5270 submit_info.signalSemaphoreCount = 0;
5271 submit_info.pSignalSemaphores = nullptr;
5272 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5275 vkQueueWaitIdle(queue);
5277 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
5278 vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
5279 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5280 vkDestroyBuffer(m_device->device(), buffer, NULL);
5281 vkFreeMemory(m_device->device(), mem, NULL);
5283 m_errorMonitor->VerifyNotFound();
5286 TEST_F(VkLayerTest, ResetEventThenSet) {
5287 TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
5289 m_errorMonitor->ExpectSuccess();
5291 ASSERT_NO_FATAL_FAILURE(InitState());
5293 VkEventCreateInfo event_create_info{};
5294 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
5295 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
5297 VkCommandPool command_pool;
5298 VkCommandPoolCreateInfo pool_create_info{};
5299 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5300 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5301 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5302 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5304 VkCommandBuffer command_buffer;
5305 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5306 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5307 command_buffer_allocate_info.commandPool = command_pool;
5308 command_buffer_allocate_info.commandBufferCount = 1;
5309 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5310 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
5312 VkQueue queue = VK_NULL_HANDLE;
5313 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5316 VkCommandBufferBeginInfo begin_info{};
5317 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5318 vkBeginCommandBuffer(command_buffer, &begin_info);
5320 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
5321 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
5322 nullptr, 0, nullptr, 0, nullptr);
5323 vkEndCommandBuffer(command_buffer);
5326 VkSubmitInfo submit_info{};
5327 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5328 submit_info.commandBufferCount = 1;
5329 submit_info.pCommandBuffers = &command_buffer;
5330 submit_info.signalSemaphoreCount = 0;
5331 submit_info.pSignalSemaphores = nullptr;
5332 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5335 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
5337 vkSetEvent(m_device->device(), event);
5338 m_errorMonitor->VerifyFound();
5341 vkQueueWaitIdle(queue);
5343 vkDestroyEvent(m_device->device(), event, nullptr);
5344 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
5345 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5348 // This is a positive test. No errors should be generated.
5349 TEST_F(VkLayerTest, TwoFencesThreeFrames) {
5350 TEST_DESCRIPTION("Two command buffers with two separate fences are each "
5351 "run through a Submit & WaitForFences cycle 3 times. This "
5352 "previously revealed a bug so running this positive test "
5353 "to prevent a regression.");
5354 m_errorMonitor->ExpectSuccess();
5356 ASSERT_NO_FATAL_FAILURE(InitState());
5357 VkQueue queue = VK_NULL_HANDLE;
5358 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
5360 static const uint32_t NUM_OBJECTS = 2;
5361 static const uint32_t NUM_FRAMES = 3;
5362 VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
5363 VkFence fences[NUM_OBJECTS] = {};
5365 VkCommandPool cmd_pool;
5366 VkCommandPoolCreateInfo cmd_pool_ci = {};
5367 cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5368 cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
5369 cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5370 VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
5371 ASSERT_VK_SUCCESS(err);
5373 VkCommandBufferAllocateInfo cmd_buf_info = {};
5374 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5375 cmd_buf_info.commandPool = cmd_pool;
5376 cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5377 cmd_buf_info.commandBufferCount = 1;
5379 VkFenceCreateInfo fence_ci = {};
5380 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5381 fence_ci.pNext = nullptr;
5384 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5385 err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
5386 ASSERT_VK_SUCCESS(err);
5387 err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
5388 ASSERT_VK_SUCCESS(err);
5391 for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
5392 for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
5393 // Create empty cmd buffer
5394 VkCommandBufferBeginInfo cmdBufBeginDesc = {};
5395 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5397 err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
5398 ASSERT_VK_SUCCESS(err);
5399 err = vkEndCommandBuffer(cmd_buffers[obj]);
5400 ASSERT_VK_SUCCESS(err);
5402 VkSubmitInfo submit_info = {};
5403 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5404 submit_info.commandBufferCount = 1;
5405 submit_info.pCommandBuffers = &cmd_buffers[obj];
5406 // Submit cmd buffer and wait for fence
5407 err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
5408 ASSERT_VK_SUCCESS(err);
5409 err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
5410 ASSERT_VK_SUCCESS(err);
5411 err = vkResetFences(m_device->device(), 1, &fences[obj]);
5412 ASSERT_VK_SUCCESS(err);
5415 m_errorMonitor->VerifyNotFound();
5416 vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
5417 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
5418 vkDestroyFence(m_device->device(), fences[i], nullptr);
5421 // This is a positive test. No errors should be generated.
5422 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
5424 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5425 "submitted on separate queues followed by a QueueWaitIdle.");
5427 ASSERT_NO_FATAL_FAILURE(InitState());
5428 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5431 m_errorMonitor->ExpectSuccess();
5433 VkSemaphore semaphore;
5434 VkSemaphoreCreateInfo semaphore_create_info{};
5435 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5436 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5438 VkCommandPool command_pool;
5439 VkCommandPoolCreateInfo pool_create_info{};
5440 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5441 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5442 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5443 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5445 VkCommandBuffer command_buffer[2];
5446 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5447 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5448 command_buffer_allocate_info.commandPool = command_pool;
5449 command_buffer_allocate_info.commandBufferCount = 2;
5450 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5451 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5453 VkQueue queue = VK_NULL_HANDLE;
5454 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5457 VkCommandBufferBeginInfo begin_info{};
5458 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5459 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5461 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5462 nullptr, 0, nullptr, 0, nullptr);
5464 VkViewport viewport{};
5465 viewport.maxDepth = 1.0f;
5466 viewport.minDepth = 0.0f;
5467 viewport.width = 512;
5468 viewport.height = 512;
5471 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5472 vkEndCommandBuffer(command_buffer[0]);
5475 VkCommandBufferBeginInfo begin_info{};
5476 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5477 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5479 VkViewport viewport{};
5480 viewport.maxDepth = 1.0f;
5481 viewport.minDepth = 0.0f;
5482 viewport.width = 512;
5483 viewport.height = 512;
5486 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5487 vkEndCommandBuffer(command_buffer[1]);
5490 VkSubmitInfo submit_info{};
5491 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5492 submit_info.commandBufferCount = 1;
5493 submit_info.pCommandBuffers = &command_buffer[0];
5494 submit_info.signalSemaphoreCount = 1;
5495 submit_info.pSignalSemaphores = &semaphore;
5496 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5499 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5500 VkSubmitInfo submit_info{};
5501 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5502 submit_info.commandBufferCount = 1;
5503 submit_info.pCommandBuffers = &command_buffer[1];
5504 submit_info.waitSemaphoreCount = 1;
5505 submit_info.pWaitSemaphores = &semaphore;
5506 submit_info.pWaitDstStageMask = flags;
5507 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5510 vkQueueWaitIdle(m_device->m_queue);
5512 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5513 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5514 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5516 m_errorMonitor->VerifyNotFound();
5519 // This is a positive test. No errors should be generated.
5520 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
5522 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5523 "submitted on separate queues, the second having a fence"
5524 "followed by a QueueWaitIdle.");
5526 ASSERT_NO_FATAL_FAILURE(InitState());
5527 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5530 m_errorMonitor->ExpectSuccess();
5533 VkFenceCreateInfo fence_create_info{};
5534 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5535 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5537 VkSemaphore semaphore;
5538 VkSemaphoreCreateInfo semaphore_create_info{};
5539 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5540 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5542 VkCommandPool command_pool;
5543 VkCommandPoolCreateInfo pool_create_info{};
5544 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5545 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5546 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5547 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5549 VkCommandBuffer command_buffer[2];
5550 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5551 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5552 command_buffer_allocate_info.commandPool = command_pool;
5553 command_buffer_allocate_info.commandBufferCount = 2;
5554 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5555 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5557 VkQueue queue = VK_NULL_HANDLE;
5558 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5561 VkCommandBufferBeginInfo begin_info{};
5562 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5563 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5565 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5566 nullptr, 0, nullptr, 0, nullptr);
5568 VkViewport viewport{};
5569 viewport.maxDepth = 1.0f;
5570 viewport.minDepth = 0.0f;
5571 viewport.width = 512;
5572 viewport.height = 512;
5575 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5576 vkEndCommandBuffer(command_buffer[0]);
5579 VkCommandBufferBeginInfo begin_info{};
5580 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5581 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5583 VkViewport viewport{};
5584 viewport.maxDepth = 1.0f;
5585 viewport.minDepth = 0.0f;
5586 viewport.width = 512;
5587 viewport.height = 512;
5590 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5591 vkEndCommandBuffer(command_buffer[1]);
5594 VkSubmitInfo submit_info{};
5595 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5596 submit_info.commandBufferCount = 1;
5597 submit_info.pCommandBuffers = &command_buffer[0];
5598 submit_info.signalSemaphoreCount = 1;
5599 submit_info.pSignalSemaphores = &semaphore;
5600 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5603 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5604 VkSubmitInfo submit_info{};
5605 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5606 submit_info.commandBufferCount = 1;
5607 submit_info.pCommandBuffers = &command_buffer[1];
5608 submit_info.waitSemaphoreCount = 1;
5609 submit_info.pWaitSemaphores = &semaphore;
5610 submit_info.pWaitDstStageMask = flags;
5611 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5614 vkQueueWaitIdle(m_device->m_queue);
5616 vkDestroyFence(m_device->device(), fence, nullptr);
5617 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5618 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5619 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5621 m_errorMonitor->VerifyNotFound();
5624 // This is a positive test. No errors should be generated.
5625 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
5627 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5628 "submitted on separate queues, the second having a fence"
5629 "followed by two consecutive WaitForFences calls on the same fence.");
5631 ASSERT_NO_FATAL_FAILURE(InitState());
5632 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5635 m_errorMonitor->ExpectSuccess();
5638 VkFenceCreateInfo fence_create_info{};
5639 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5640 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5642 VkSemaphore semaphore;
5643 VkSemaphoreCreateInfo semaphore_create_info{};
5644 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5645 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5647 VkCommandPool command_pool;
5648 VkCommandPoolCreateInfo pool_create_info{};
5649 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5650 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5651 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5652 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5654 VkCommandBuffer command_buffer[2];
5655 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5656 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5657 command_buffer_allocate_info.commandPool = command_pool;
5658 command_buffer_allocate_info.commandBufferCount = 2;
5659 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5660 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5662 VkQueue queue = VK_NULL_HANDLE;
5663 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5666 VkCommandBufferBeginInfo begin_info{};
5667 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5668 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5670 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5671 nullptr, 0, nullptr, 0, nullptr);
5673 VkViewport viewport{};
5674 viewport.maxDepth = 1.0f;
5675 viewport.minDepth = 0.0f;
5676 viewport.width = 512;
5677 viewport.height = 512;
5680 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5681 vkEndCommandBuffer(command_buffer[0]);
5684 VkCommandBufferBeginInfo begin_info{};
5685 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5686 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5688 VkViewport viewport{};
5689 viewport.maxDepth = 1.0f;
5690 viewport.minDepth = 0.0f;
5691 viewport.width = 512;
5692 viewport.height = 512;
5695 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5696 vkEndCommandBuffer(command_buffer[1]);
5699 VkSubmitInfo submit_info{};
5700 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5701 submit_info.commandBufferCount = 1;
5702 submit_info.pCommandBuffers = &command_buffer[0];
5703 submit_info.signalSemaphoreCount = 1;
5704 submit_info.pSignalSemaphores = &semaphore;
5705 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5708 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5709 VkSubmitInfo submit_info{};
5710 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5711 submit_info.commandBufferCount = 1;
5712 submit_info.pCommandBuffers = &command_buffer[1];
5713 submit_info.waitSemaphoreCount = 1;
5714 submit_info.pWaitSemaphores = &semaphore;
5715 submit_info.pWaitDstStageMask = flags;
5716 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5719 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5720 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5722 vkDestroyFence(m_device->device(), fence, nullptr);
5723 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5724 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5725 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5727 m_errorMonitor->VerifyNotFound();
5730 TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
5732 ASSERT_NO_FATAL_FAILURE(InitState());
5733 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
5734 printf("Test requires two queues, skipping\n");
5740 m_errorMonitor->ExpectSuccess();
5742 VkQueue q0 = m_device->m_queue;
5743 VkQueue q1 = nullptr;
5744 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
5745 ASSERT_NE(q1, nullptr);
5747 // An (empty) command buffer. We must have work in the first submission --
5748 // the layer treats unfenced work differently from fenced work.
5749 VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
5751 err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
5752 ASSERT_VK_SUCCESS(err);
5753 VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
5754 VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
5756 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
5757 ASSERT_VK_SUCCESS(err);
5758 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
5759 err = vkBeginCommandBuffer(cb, &cbbi);
5760 ASSERT_VK_SUCCESS(err);
5761 err = vkEndCommandBuffer(cb);
5762 ASSERT_VK_SUCCESS(err);
5765 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5767 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
5768 ASSERT_VK_SUCCESS(err);
5770 // First submission, to q0
5771 VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
5773 err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
5774 ASSERT_VK_SUCCESS(err);
5776 // Second submission, to q1, waiting on s
5777 VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
5778 VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
5780 err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
5781 ASSERT_VK_SUCCESS(err);
5784 err = vkQueueWaitIdle(q0);
5785 ASSERT_VK_SUCCESS(err);
5787 // Command buffer should have been completed (it was on q0); reset the pool.
5788 vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
5790 m_errorMonitor->VerifyNotFound();
5792 // Force device completely idle and clean up resources
5793 vkDeviceWaitIdle(m_device->device());
5794 vkDestroyCommandPool(m_device->device(), pool, nullptr);
5795 vkDestroySemaphore(m_device->device(), s, nullptr);
5798 // This is a positive test. No errors should be generated.
5799 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
5801 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5802 "submitted on separate queues, the second having a fence, "
5803 "followed by a WaitForFences call.");
5805 ASSERT_NO_FATAL_FAILURE(InitState());
5806 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
5809 m_errorMonitor->ExpectSuccess();
5811 ASSERT_NO_FATAL_FAILURE(InitState());
5813 VkFenceCreateInfo fence_create_info{};
5814 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5815 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5817 VkSemaphore semaphore;
5818 VkSemaphoreCreateInfo semaphore_create_info{};
5819 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5820 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5822 VkCommandPool command_pool;
5823 VkCommandPoolCreateInfo pool_create_info{};
5824 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5825 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5826 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5827 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5829 VkCommandBuffer command_buffer[2];
5830 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5831 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5832 command_buffer_allocate_info.commandPool = command_pool;
5833 command_buffer_allocate_info.commandBufferCount = 2;
5834 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5835 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5837 VkQueue queue = VK_NULL_HANDLE;
5838 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
5841 VkCommandBufferBeginInfo begin_info{};
5842 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5843 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5845 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5846 nullptr, 0, nullptr, 0, nullptr);
5848 VkViewport viewport{};
5849 viewport.maxDepth = 1.0f;
5850 viewport.minDepth = 0.0f;
5851 viewport.width = 512;
5852 viewport.height = 512;
5855 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5856 vkEndCommandBuffer(command_buffer[0]);
5859 VkCommandBufferBeginInfo begin_info{};
5860 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5861 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5863 VkViewport viewport{};
5864 viewport.maxDepth = 1.0f;
5865 viewport.minDepth = 0.0f;
5866 viewport.width = 512;
5867 viewport.height = 512;
5870 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5871 vkEndCommandBuffer(command_buffer[1]);
5874 VkSubmitInfo submit_info{};
5875 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5876 submit_info.commandBufferCount = 1;
5877 submit_info.pCommandBuffers = &command_buffer[0];
5878 submit_info.signalSemaphoreCount = 1;
5879 submit_info.pSignalSemaphores = &semaphore;
5880 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
5883 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5884 VkSubmitInfo submit_info{};
5885 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5886 submit_info.commandBufferCount = 1;
5887 submit_info.pCommandBuffers = &command_buffer[1];
5888 submit_info.waitSemaphoreCount = 1;
5889 submit_info.pWaitSemaphores = &semaphore;
5890 submit_info.pWaitDstStageMask = flags;
5891 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5894 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5896 vkDestroyFence(m_device->device(), fence, nullptr);
5897 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5898 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5899 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
5901 m_errorMonitor->VerifyNotFound();
5904 // This is a positive test. No errors should be generated.
5905 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
5907 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
5908 "on the same queue, sharing a signal/wait semaphore, the "
5909 "second having a fence, "
5910 "followed by a WaitForFences call.");
5912 m_errorMonitor->ExpectSuccess();
5914 ASSERT_NO_FATAL_FAILURE(InitState());
5916 VkFenceCreateInfo fence_create_info{};
5917 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
5918 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
5920 VkSemaphore semaphore;
5921 VkSemaphoreCreateInfo semaphore_create_info{};
5922 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5923 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
5925 VkCommandPool command_pool;
5926 VkCommandPoolCreateInfo pool_create_info{};
5927 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5928 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
5929 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5930 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
5932 VkCommandBuffer command_buffer[2];
5933 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5934 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5935 command_buffer_allocate_info.commandPool = command_pool;
5936 command_buffer_allocate_info.commandBufferCount = 2;
5937 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5938 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
5941 VkCommandBufferBeginInfo begin_info{};
5942 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5943 vkBeginCommandBuffer(command_buffer[0], &begin_info);
5945 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
5946 nullptr, 0, nullptr, 0, nullptr);
5948 VkViewport viewport{};
5949 viewport.maxDepth = 1.0f;
5950 viewport.minDepth = 0.0f;
5951 viewport.width = 512;
5952 viewport.height = 512;
5955 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
5956 vkEndCommandBuffer(command_buffer[0]);
5959 VkCommandBufferBeginInfo begin_info{};
5960 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5961 vkBeginCommandBuffer(command_buffer[1], &begin_info);
5963 VkViewport viewport{};
5964 viewport.maxDepth = 1.0f;
5965 viewport.minDepth = 0.0f;
5966 viewport.width = 512;
5967 viewport.height = 512;
5970 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
5971 vkEndCommandBuffer(command_buffer[1]);
5974 VkSubmitInfo submit_info{};
5975 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5976 submit_info.commandBufferCount = 1;
5977 submit_info.pCommandBuffers = &command_buffer[0];
5978 submit_info.signalSemaphoreCount = 1;
5979 submit_info.pSignalSemaphores = &semaphore;
5980 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5983 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
5984 VkSubmitInfo submit_info{};
5985 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5986 submit_info.commandBufferCount = 1;
5987 submit_info.pCommandBuffers = &command_buffer[1];
5988 submit_info.waitSemaphoreCount = 1;
5989 submit_info.pWaitSemaphores = &semaphore;
5990 submit_info.pWaitDstStageMask = flags;
5991 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
5994 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5996 vkDestroyFence(m_device->device(), fence, nullptr);
5997 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5998 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
5999 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6001 m_errorMonitor->VerifyNotFound();
6004 // This is a positive test. No errors should be generated.
6005 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
6007 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6008 "on the same queue, no fences, followed by a third QueueSubmit with NO "
6009 "SubmitInfos but with a fence, followed by a WaitForFences call.");
6011 m_errorMonitor->ExpectSuccess();
6013 ASSERT_NO_FATAL_FAILURE(InitState());
6015 VkFenceCreateInfo fence_create_info{};
6016 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6017 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6019 VkCommandPool command_pool;
6020 VkCommandPoolCreateInfo pool_create_info{};
6021 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6022 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6023 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6024 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6026 VkCommandBuffer command_buffer[2];
6027 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6028 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6029 command_buffer_allocate_info.commandPool = command_pool;
6030 command_buffer_allocate_info.commandBufferCount = 2;
6031 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6032 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6035 VkCommandBufferBeginInfo begin_info{};
6036 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6037 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6039 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6040 nullptr, 0, nullptr, 0, nullptr);
6042 VkViewport viewport{};
6043 viewport.maxDepth = 1.0f;
6044 viewport.minDepth = 0.0f;
6045 viewport.width = 512;
6046 viewport.height = 512;
6049 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6050 vkEndCommandBuffer(command_buffer[0]);
6053 VkCommandBufferBeginInfo begin_info{};
6054 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6055 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6057 VkViewport viewport{};
6058 viewport.maxDepth = 1.0f;
6059 viewport.minDepth = 0.0f;
6060 viewport.width = 512;
6061 viewport.height = 512;
6064 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6065 vkEndCommandBuffer(command_buffer[1]);
6068 VkSubmitInfo submit_info{};
6069 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6070 submit_info.commandBufferCount = 1;
6071 submit_info.pCommandBuffers = &command_buffer[0];
6072 submit_info.signalSemaphoreCount = 0;
6073 submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6074 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6077 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6078 VkSubmitInfo submit_info{};
6079 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6080 submit_info.commandBufferCount = 1;
6081 submit_info.pCommandBuffers = &command_buffer[1];
6082 submit_info.waitSemaphoreCount = 0;
6083 submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6084 submit_info.pWaitDstStageMask = flags;
6085 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6088 vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
6090 VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6091 ASSERT_VK_SUCCESS(err);
6093 vkDestroyFence(m_device->device(), fence, nullptr);
6094 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6095 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6097 m_errorMonitor->VerifyNotFound();
6100 // This is a positive test. No errors should be generated.
6101 TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
6103 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
6104 "on the same queue, the second having a fence, followed "
6105 "by a WaitForFences call.");
6107 m_errorMonitor->ExpectSuccess();
6109 ASSERT_NO_FATAL_FAILURE(InitState());
6111 VkFenceCreateInfo fence_create_info{};
6112 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6113 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6115 VkCommandPool command_pool;
6116 VkCommandPoolCreateInfo pool_create_info{};
6117 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6118 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6119 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6120 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6122 VkCommandBuffer command_buffer[2];
6123 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6124 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6125 command_buffer_allocate_info.commandPool = command_pool;
6126 command_buffer_allocate_info.commandBufferCount = 2;
6127 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6128 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6131 VkCommandBufferBeginInfo begin_info{};
6132 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6133 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6135 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6136 nullptr, 0, nullptr, 0, nullptr);
6138 VkViewport viewport{};
6139 viewport.maxDepth = 1.0f;
6140 viewport.minDepth = 0.0f;
6141 viewport.width = 512;
6142 viewport.height = 512;
6145 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6146 vkEndCommandBuffer(command_buffer[0]);
6149 VkCommandBufferBeginInfo begin_info{};
6150 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6151 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6153 VkViewport viewport{};
6154 viewport.maxDepth = 1.0f;
6155 viewport.minDepth = 0.0f;
6156 viewport.width = 512;
6157 viewport.height = 512;
6160 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6161 vkEndCommandBuffer(command_buffer[1]);
6164 VkSubmitInfo submit_info{};
6165 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6166 submit_info.commandBufferCount = 1;
6167 submit_info.pCommandBuffers = &command_buffer[0];
6168 submit_info.signalSemaphoreCount = 0;
6169 submit_info.pSignalSemaphores = VK_NULL_HANDLE;
6170 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6173 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6174 VkSubmitInfo submit_info{};
6175 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6176 submit_info.commandBufferCount = 1;
6177 submit_info.pCommandBuffers = &command_buffer[1];
6178 submit_info.waitSemaphoreCount = 0;
6179 submit_info.pWaitSemaphores = VK_NULL_HANDLE;
6180 submit_info.pWaitDstStageMask = flags;
6181 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
6184 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6186 vkDestroyFence(m_device->device(), fence, nullptr);
6187 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6188 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6190 m_errorMonitor->VerifyNotFound();
6193 // This is a positive test. No errors should be generated.
6194 TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
6196 TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
6197 "QueueSubmit call followed by a WaitForFences call.");
6198 ASSERT_NO_FATAL_FAILURE(InitState());
6200 m_errorMonitor->ExpectSuccess();
6203 VkFenceCreateInfo fence_create_info{};
6204 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
6205 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
6207 VkSemaphore semaphore;
6208 VkSemaphoreCreateInfo semaphore_create_info{};
6209 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6210 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
6212 VkCommandPool command_pool;
6213 VkCommandPoolCreateInfo pool_create_info{};
6214 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
6215 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
6216 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6217 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
6219 VkCommandBuffer command_buffer[2];
6220 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
6221 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
6222 command_buffer_allocate_info.commandPool = command_pool;
6223 command_buffer_allocate_info.commandBufferCount = 2;
6224 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
6225 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
6228 VkCommandBufferBeginInfo begin_info{};
6229 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6230 vkBeginCommandBuffer(command_buffer[0], &begin_info);
6232 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6233 nullptr, 0, nullptr, 0, nullptr);
6235 VkViewport viewport{};
6236 viewport.maxDepth = 1.0f;
6237 viewport.minDepth = 0.0f;
6238 viewport.width = 512;
6239 viewport.height = 512;
6242 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
6243 vkEndCommandBuffer(command_buffer[0]);
6246 VkCommandBufferBeginInfo begin_info{};
6247 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
6248 vkBeginCommandBuffer(command_buffer[1], &begin_info);
6250 VkViewport viewport{};
6251 viewport.maxDepth = 1.0f;
6252 viewport.minDepth = 0.0f;
6253 viewport.width = 512;
6254 viewport.height = 512;
6257 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
6258 vkEndCommandBuffer(command_buffer[1]);
6261 VkSubmitInfo submit_info[2];
6262 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
6264 submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6265 submit_info[0].pNext = NULL;
6266 submit_info[0].commandBufferCount = 1;
6267 submit_info[0].pCommandBuffers = &command_buffer[0];
6268 submit_info[0].signalSemaphoreCount = 1;
6269 submit_info[0].pSignalSemaphores = &semaphore;
6270 submit_info[0].waitSemaphoreCount = 0;
6271 submit_info[0].pWaitSemaphores = NULL;
6272 submit_info[0].pWaitDstStageMask = 0;
6274 submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6275 submit_info[1].pNext = NULL;
6276 submit_info[1].commandBufferCount = 1;
6277 submit_info[1].pCommandBuffers = &command_buffer[1];
6278 submit_info[1].waitSemaphoreCount = 1;
6279 submit_info[1].pWaitSemaphores = &semaphore;
6280 submit_info[1].pWaitDstStageMask = flags;
6281 submit_info[1].signalSemaphoreCount = 0;
6282 submit_info[1].pSignalSemaphores = NULL;
6283 vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
6286 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
6288 vkDestroyFence(m_device->device(), fence, nullptr);
6289 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
6290 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
6291 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
6293 m_errorMonitor->VerifyNotFound();
6296 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
6297 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
6298 "state is required but not correctly bound.");
6300 ASSERT_NO_FATAL_FAILURE(InitState());
6301 // Dynamic depth bias
6302 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
6303 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias);
6304 m_errorMonitor->VerifyFound();
6307 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
6308 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic "
6309 "state is required but not correctly bound.");
6311 ASSERT_NO_FATAL_FAILURE(InitState());
6312 // Dynamic line width
6313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
6314 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth);
6315 m_errorMonitor->VerifyFound();
6318 TEST_F(VkLayerTest, DynamicViewportNotBound) {
6319 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic "
6320 "state is required but not correctly bound.");
6322 ASSERT_NO_FATAL_FAILURE(InitState());
6323 // Dynamic viewport state
6324 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, but were not provided");
6325 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
6326 m_errorMonitor->VerifyFound();
6329 TEST_F(VkLayerTest, DynamicScissorNotBound) {
6330 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic "
6331 "state is required but not correctly bound.");
6333 ASSERT_NO_FATAL_FAILURE(InitState());
6334 // Dynamic scissor state
6335 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, but were not provided");
6336 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
6337 m_errorMonitor->VerifyFound();
6340 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
6341 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants "
6342 "dynamic state is required but not correctly bound.");
6344 ASSERT_NO_FATAL_FAILURE(InitState());
6345 // Dynamic blend constant state
6346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6347 "Dynamic blend constants state not set for this command buffer");
6348 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend);
6349 m_errorMonitor->VerifyFound();
6352 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
6353 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic "
6354 "state is required but not correctly bound.");
6356 ASSERT_NO_FATAL_FAILURE(InitState());
6357 if (!m_device->phy().features().depthBounds) {
6358 printf("Device does not support depthBounds test; skipped.\n");
6361 // Dynamic depth bounds
6362 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6363 "Dynamic depth bounds state not set for this command buffer");
6364 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds);
6365 m_errorMonitor->VerifyFound();
6368 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
6369 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic "
6370 "state is required but not correctly bound.");
6372 ASSERT_NO_FATAL_FAILURE(InitState());
6373 // Dynamic stencil read mask
6374 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6375 "Dynamic stencil read mask state not set for this command buffer");
6376 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask);
6377 m_errorMonitor->VerifyFound();
6380 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
6381 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic"
6382 " state is required but not correctly bound.");
6384 ASSERT_NO_FATAL_FAILURE(InitState());
6385 // Dynamic stencil write mask
6386 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6387 "Dynamic stencil write mask state not set for this command buffer");
6388 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask);
6389 m_errorMonitor->VerifyFound();
6392 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
6393 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic "
6394 "state is required but not correctly bound.");
6396 ASSERT_NO_FATAL_FAILURE(InitState());
6397 // Dynamic stencil reference
6398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6399 "Dynamic stencil reference state not set for this command buffer");
6400 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference);
6401 m_errorMonitor->VerifyFound();
6404 TEST_F(VkLayerTest, IndexBufferNotBound) {
6405 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
6407 ASSERT_NO_FATAL_FAILURE(InitState());
6408 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6409 "Index buffer object not bound to this command buffer when Indexed ");
6410 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer);
6411 m_errorMonitor->VerifyFound();
6414 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
6415 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6416 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
6419 ASSERT_NO_FATAL_FAILURE(InitState());
6420 ASSERT_NO_FATAL_FAILURE(InitViewport());
6421 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6423 // We luck out b/c by default the framework creates CB w/ the
6424 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
6425 BeginCommandBuffer();
6426 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
6429 // Bypass framework since it does the waits automatically
6430 VkResult err = VK_SUCCESS;
6431 VkSubmitInfo submit_info;
6432 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6433 submit_info.pNext = NULL;
6434 submit_info.waitSemaphoreCount = 0;
6435 submit_info.pWaitSemaphores = NULL;
6436 submit_info.pWaitDstStageMask = NULL;
6437 submit_info.commandBufferCount = 1;
6438 submit_info.pCommandBuffers = &m_commandBuffer->handle();
6439 submit_info.signalSemaphoreCount = 0;
6440 submit_info.pSignalSemaphores = NULL;
6442 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6443 ASSERT_VK_SUCCESS(err);
6445 // Cause validation error by re-submitting cmd buffer that should only be
6447 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6449 m_errorMonitor->VerifyFound();
6452 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
6453 // Initiate Draw w/o a PSO bound
6456 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of "
6458 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ");
6460 ASSERT_NO_FATAL_FAILURE(InitState());
6461 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6463 // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
6464 // descriptor from it
6465 VkDescriptorPoolSize ds_type_count = {};
6466 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
6467 ds_type_count.descriptorCount = 1;
6469 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6470 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6471 ds_pool_ci.pNext = NULL;
6472 ds_pool_ci.flags = 0;
6473 ds_pool_ci.maxSets = 1;
6474 ds_pool_ci.poolSizeCount = 1;
6475 ds_pool_ci.pPoolSizes = &ds_type_count;
6477 VkDescriptorPool ds_pool;
6478 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6479 ASSERT_VK_SUCCESS(err);
6481 VkDescriptorSetLayoutBinding dsl_binding = {};
6482 dsl_binding.binding = 0;
6483 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6484 dsl_binding.descriptorCount = 1;
6485 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6486 dsl_binding.pImmutableSamplers = NULL;
6488 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6489 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6490 ds_layout_ci.pNext = NULL;
6491 ds_layout_ci.bindingCount = 1;
6492 ds_layout_ci.pBindings = &dsl_binding;
6494 VkDescriptorSetLayout ds_layout;
6495 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6496 ASSERT_VK_SUCCESS(err);
6498 VkDescriptorSet descriptorSet;
6499 VkDescriptorSetAllocateInfo alloc_info = {};
6500 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6501 alloc_info.descriptorSetCount = 1;
6502 alloc_info.descriptorPool = ds_pool;
6503 alloc_info.pSetLayouts = &ds_layout;
6504 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6506 m_errorMonitor->VerifyFound();
6508 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6509 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6512 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
6515 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6516 "It is invalid to call vkFreeDescriptorSets() with a pool created "
6517 "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
6519 ASSERT_NO_FATAL_FAILURE(InitState());
6520 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6522 VkDescriptorPoolSize ds_type_count = {};
6523 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6524 ds_type_count.descriptorCount = 1;
6526 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6527 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6528 ds_pool_ci.pNext = NULL;
6529 ds_pool_ci.maxSets = 1;
6530 ds_pool_ci.poolSizeCount = 1;
6531 ds_pool_ci.flags = 0;
6532 // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
6533 // app can only call vkResetDescriptorPool on this pool.;
6534 ds_pool_ci.pPoolSizes = &ds_type_count;
6536 VkDescriptorPool ds_pool;
6537 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6538 ASSERT_VK_SUCCESS(err);
6540 VkDescriptorSetLayoutBinding dsl_binding = {};
6541 dsl_binding.binding = 0;
6542 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6543 dsl_binding.descriptorCount = 1;
6544 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
6545 dsl_binding.pImmutableSamplers = NULL;
6547 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6548 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6549 ds_layout_ci.pNext = NULL;
6550 ds_layout_ci.bindingCount = 1;
6551 ds_layout_ci.pBindings = &dsl_binding;
6553 VkDescriptorSetLayout ds_layout;
6554 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6555 ASSERT_VK_SUCCESS(err);
6557 VkDescriptorSet descriptorSet;
6558 VkDescriptorSetAllocateInfo alloc_info = {};
6559 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6560 alloc_info.descriptorSetCount = 1;
6561 alloc_info.descriptorPool = ds_pool;
6562 alloc_info.pSetLayouts = &ds_layout;
6563 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6564 ASSERT_VK_SUCCESS(err);
6566 err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
6567 m_errorMonitor->VerifyFound();
6569 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6570 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6573 TEST_F(VkLayerTest, InvalidDescriptorPool) {
6574 // Attempt to clear Descriptor Pool with bad object.
6575 // ObjectTracker should catch this.
6577 ASSERT_NO_FATAL_FAILURE(InitState());
6578 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001");
6579 uint64_t fake_pool_handle = 0xbaad6001;
6580 VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
6581 vkResetDescriptorPool(device(), bad_pool, 0);
6582 m_errorMonitor->VerifyFound();
6585 TEST_F(VkLayerTest, InvalidDescriptorSet) {
6586 // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
6587 // ObjectTracker should catch this.
6588 // Create a valid cmd buffer
6589 // call vkCmdBindDescriptorSets w/ false Descriptor Set
6591 uint64_t fake_set_handle = 0xbaad6001;
6592 VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
6594 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001");
6596 ASSERT_NO_FATAL_FAILURE(InitState());
6598 VkDescriptorSetLayoutBinding layout_bindings[1] = {};
6599 layout_bindings[0].binding = 0;
6600 layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6601 layout_bindings[0].descriptorCount = 1;
6602 layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
6603 layout_bindings[0].pImmutableSamplers = NULL;
6605 VkDescriptorSetLayout descriptor_set_layout;
6606 VkDescriptorSetLayoutCreateInfo dslci = {};
6607 dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6609 dslci.bindingCount = 1;
6610 dslci.pBindings = layout_bindings;
6611 err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout);
6612 ASSERT_VK_SUCCESS(err);
6614 VkPipelineLayout pipeline_layout;
6615 VkPipelineLayoutCreateInfo plci = {};
6616 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6618 plci.setLayoutCount = 1;
6619 plci.pSetLayouts = &descriptor_set_layout;
6620 err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6621 ASSERT_VK_SUCCESS(err);
6623 BeginCommandBuffer();
6624 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0,
6626 m_errorMonitor->VerifyFound();
6628 vkDestroyPipelineLayout(device(), pipeline_layout, NULL);
6629 vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL);
6632 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
6633 // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
6634 // ObjectTracker should catch this.
6635 uint64_t fake_layout_handle = 0xbaad6001;
6636 VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
6637 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001");
6638 ASSERT_NO_FATAL_FAILURE(InitState());
6639 VkPipelineLayout pipeline_layout;
6640 VkPipelineLayoutCreateInfo plci = {};
6641 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6643 plci.setLayoutCount = 1;
6644 plci.pSetLayouts = &bad_layout;
6645 vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
6647 m_errorMonitor->VerifyFound();
6650 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
6651 TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
6652 "1) A uniform buffer update must have a valid buffer index."
6653 "2) When using an array of descriptors in a single WriteDescriptor,"
6654 " the descriptor types and stageflags must all be the same."
6655 "3) Immutable Sampler state must match across descriptors");
6657 const char *invalid_BufferInfo_ErrorMessage =
6658 "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
6659 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
6660 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
6661 const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set ";
6662 const char *immutable_ErrorMessage = "Attempting write update to descriptor set ";
6664 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
6666 ASSERT_NO_FATAL_FAILURE(InitState());
6667 VkDescriptorPoolSize ds_type_count[4] = {};
6668 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6669 ds_type_count[0].descriptorCount = 1;
6670 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6671 ds_type_count[1].descriptorCount = 1;
6672 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
6673 ds_type_count[2].descriptorCount = 1;
6674 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
6675 ds_type_count[3].descriptorCount = 1;
6677 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6678 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6679 ds_pool_ci.maxSets = 1;
6680 ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
6681 ds_pool_ci.pPoolSizes = ds_type_count;
6683 VkDescriptorPool ds_pool;
6684 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6685 ASSERT_VK_SUCCESS(err);
6687 VkDescriptorSetLayoutBinding layout_binding[3] = {};
6688 layout_binding[0].binding = 0;
6689 layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6690 layout_binding[0].descriptorCount = 1;
6691 layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
6692 layout_binding[0].pImmutableSamplers = NULL;
6694 layout_binding[1].binding = 1;
6695 layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6696 layout_binding[1].descriptorCount = 1;
6697 layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6698 layout_binding[1].pImmutableSamplers = NULL;
6700 VkSamplerCreateInfo sampler_ci = {};
6701 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6702 sampler_ci.pNext = NULL;
6703 sampler_ci.magFilter = VK_FILTER_NEAREST;
6704 sampler_ci.minFilter = VK_FILTER_NEAREST;
6705 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
6706 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6707 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6708 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
6709 sampler_ci.mipLodBias = 1.0;
6710 sampler_ci.anisotropyEnable = VK_FALSE;
6711 sampler_ci.maxAnisotropy = 1;
6712 sampler_ci.compareEnable = VK_FALSE;
6713 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
6714 sampler_ci.minLod = 1.0;
6715 sampler_ci.maxLod = 1.0;
6716 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
6717 sampler_ci.unnormalizedCoordinates = VK_FALSE;
6720 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
6721 ASSERT_VK_SUCCESS(err);
6723 layout_binding[2].binding = 2;
6724 layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6725 layout_binding[2].descriptorCount = 1;
6726 layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6727 layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
6729 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6730 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6731 ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
6732 ds_layout_ci.pBindings = layout_binding;
6733 VkDescriptorSetLayout ds_layout;
6734 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6735 ASSERT_VK_SUCCESS(err);
6737 VkDescriptorSetAllocateInfo alloc_info = {};
6738 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6739 alloc_info.descriptorSetCount = 1;
6740 alloc_info.descriptorPool = ds_pool;
6741 alloc_info.pSetLayouts = &ds_layout;
6742 VkDescriptorSet descriptorSet;
6743 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
6744 ASSERT_VK_SUCCESS(err);
6746 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6747 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6748 pipeline_layout_ci.pNext = NULL;
6749 pipeline_layout_ci.setLayoutCount = 1;
6750 pipeline_layout_ci.pSetLayouts = &ds_layout;
6752 VkPipelineLayout pipeline_layout;
6753 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6754 ASSERT_VK_SUCCESS(err);
6756 VkWriteDescriptorSet descriptor_write = {};
6757 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6758 descriptor_write.dstSet = descriptorSet;
6759 descriptor_write.dstBinding = 0;
6760 descriptor_write.descriptorCount = 1;
6761 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
6763 // 1) The uniform buffer is intentionally invalid here
6764 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6765 m_errorMonitor->VerifyFound();
6767 // Create a buffer to update the descriptor with
6769 VkBufferCreateInfo buffCI = {};
6770 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6772 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
6773 buffCI.queueFamilyIndexCount = 1;
6774 buffCI.pQueueFamilyIndices = &qfi;
6777 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
6778 ASSERT_VK_SUCCESS(err);
6779 VkDescriptorBufferInfo buffInfo = {};
6780 buffInfo.buffer = dyub;
6781 buffInfo.offset = 0;
6782 buffInfo.range = 1024;
6784 descriptor_write.pBufferInfo = &buffInfo;
6785 descriptor_write.descriptorCount = 2;
6787 // 2) The stateFlags don't match between the first and second descriptor
6788 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
6789 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6790 m_errorMonitor->VerifyFound();
6792 // 3) The second descriptor has a null_ptr pImmutableSamplers and
6793 // the third descriptor contains an immutable sampler
6794 descriptor_write.dstBinding = 1;
6795 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
6797 // Make pImageInfo index non-null to avoid complaints of it missing
6798 VkDescriptorImageInfo imageInfo = {};
6799 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6800 descriptor_write.pImageInfo = &imageInfo;
6801 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
6802 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6803 m_errorMonitor->VerifyFound();
6805 vkDestroyBuffer(m_device->device(), dyub, NULL);
6806 vkDestroySampler(m_device->device(), sampler, NULL);
6807 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
6808 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
6809 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
6812 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
6813 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
6814 "due to a buffer dependency being destroyed.");
6815 ASSERT_NO_FATAL_FAILURE(InitState());
6819 VkMemoryRequirements mem_reqs;
6821 VkBufferCreateInfo buf_info = {};
6822 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6823 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
6824 buf_info.size = 256;
6825 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
6826 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
6827 ASSERT_VK_SUCCESS(err);
6829 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
6831 VkMemoryAllocateInfo alloc_info = {};
6832 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6833 alloc_info.allocationSize = 256;
6835 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6837 vkDestroyBuffer(m_device->device(), buffer, NULL);
6840 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
6841 ASSERT_VK_SUCCESS(err);
6843 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
6844 ASSERT_VK_SUCCESS(err);
6846 m_commandBuffer->BeginCommandBuffer();
6847 vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
6848 m_commandBuffer->EndCommandBuffer();
6850 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
6851 // Destroy buffer dependency prior to submit to cause ERROR
6852 vkDestroyBuffer(m_device->device(), buffer, NULL);
6854 VkSubmitInfo submit_info = {};
6855 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6856 submit_info.commandBufferCount = 1;
6857 submit_info.pCommandBuffers = &m_commandBuffer->handle();
6858 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
6860 m_errorMonitor->VerifyFound();
6861 vkFreeMemory(m_device->handle(), mem, NULL);
6864 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
6865 TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
6867 ASSERT_NO_FATAL_FAILURE(InitState());
6868 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6870 VkDescriptorPoolSize ds_type_count;
6871 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6872 ds_type_count.descriptorCount = 1;
6874 VkDescriptorPoolCreateInfo ds_pool_ci = {};
6875 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
6876 ds_pool_ci.maxSets = 1;
6877 ds_pool_ci.poolSizeCount = 1;
6878 ds_pool_ci.pPoolSizes = &ds_type_count;
6880 VkDescriptorPool ds_pool;
6881 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
6882 ASSERT_VK_SUCCESS(err);
6884 VkDescriptorSetLayoutBinding layout_binding;
6885 layout_binding.binding = 0;
6886 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6887 layout_binding.descriptorCount = 1;
6888 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
6889 layout_binding.pImmutableSamplers = NULL;
6891 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
6892 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6893 ds_layout_ci.bindingCount = 1;
6894 ds_layout_ci.pBindings = &layout_binding;
6895 VkDescriptorSetLayout ds_layout;
6896 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
6897 ASSERT_VK_SUCCESS(err);
6899 VkDescriptorSetAllocateInfo alloc_info = {};
6900 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
6901 alloc_info.descriptorSetCount = 1;
6902 alloc_info.descriptorPool = ds_pool;
6903 alloc_info.pSetLayouts = &ds_layout;
6904 VkDescriptorSet descriptor_set;
6905 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
6906 ASSERT_VK_SUCCESS(err);
6908 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
6909 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
6910 pipeline_layout_ci.pNext = NULL;
6911 pipeline_layout_ci.setLayoutCount = 1;
6912 pipeline_layout_ci.pSetLayouts = &ds_layout;
6914 VkPipelineLayout pipeline_layout;
6915 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
6916 ASSERT_VK_SUCCESS(err);
6919 uint32_t queue_family_index = 0;
6920 VkBufferCreateInfo buffer_create_info = {};
6921 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6922 buffer_create_info.size = 1024;
6923 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
6924 buffer_create_info.queueFamilyIndexCount = 1;
6925 buffer_create_info.pQueueFamilyIndices = &queue_family_index;
6927 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
6928 ASSERT_VK_SUCCESS(err);
6930 VkMemoryRequirements memory_reqs;
6931 VkDeviceMemory buffer_memory;
6933 VkMemoryAllocateInfo memory_info = {};
6934 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6935 memory_info.allocationSize = 0;
6936 memory_info.memoryTypeIndex = 0;
6938 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
6939 memory_info.allocationSize = memory_reqs.size;
6940 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
6943 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
6944 ASSERT_VK_SUCCESS(err);
6945 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
6946 ASSERT_VK_SUCCESS(err);
6949 VkBufferViewCreateInfo bvci = {};
6950 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
6951 bvci.buffer = buffer;
6952 bvci.format = VK_FORMAT_R8_UNORM;
6953 bvci.range = VK_WHOLE_SIZE;
6955 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
6956 ASSERT_VK_SUCCESS(err);
6958 VkWriteDescriptorSet descriptor_write = {};
6959 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6960 descriptor_write.dstSet = descriptor_set;
6961 descriptor_write.dstBinding = 0;
6962 descriptor_write.descriptorCount = 1;
6963 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
6964 descriptor_write.pTexelBufferView = &view;
6966 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6968 char const *vsSource = "#version 450\n"
6970 "out gl_PerVertex { \n"
6971 " vec4 gl_Position;\n"
6974 " gl_Position = vec4(1);\n"
6976 char const *fsSource = "#version 450\n"
6978 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
6979 "layout(location=0) out vec4 x;\n"
6981 " x = imageLoad(s, 0);\n"
6983 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
6984 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6985 VkPipelineObj pipe(m_device);
6986 pipe.AddShader(&vs);
6987 pipe.AddShader(&fs);
6988 pipe.AddColorAttachment();
6989 pipe.CreateVKPipeline(pipeline_layout, renderPass());
6991 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
6992 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
6994 BeginCommandBuffer();
6995 VkViewport viewport = {0, 0, 16, 16, 0, 1};
6996 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
6997 VkRect2D scissor = {{0, 0}, {16, 16}};
6998 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
6999 // Bind pipeline to cmd buffer
7000 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7001 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7002 &descriptor_set, 0, nullptr);
7006 // Delete BufferView in order to invalidate cmd buffer
7007 vkDestroyBufferView(m_device->device(), view, NULL);
7008 // Now attempt submit of cmd buffer
7009 VkSubmitInfo submit_info = {};
7010 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7011 submit_info.commandBufferCount = 1;
7012 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7013 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7014 m_errorMonitor->VerifyFound();
7017 vkDestroyBuffer(m_device->device(), buffer, NULL);
7018 vkFreeMemory(m_device->device(), buffer_memory, NULL);
7019 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7020 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7021 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7024 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
7025 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7026 "due to an image dependency being destroyed.");
7027 ASSERT_NO_FATAL_FAILURE(InitState());
7030 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7031 VkImageCreateInfo image_create_info = {};
7032 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7033 image_create_info.pNext = NULL;
7034 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7035 image_create_info.format = tex_format;
7036 image_create_info.extent.width = 32;
7037 image_create_info.extent.height = 32;
7038 image_create_info.extent.depth = 1;
7039 image_create_info.mipLevels = 1;
7040 image_create_info.arrayLayers = 1;
7041 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7042 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7043 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7044 image_create_info.flags = 0;
7045 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7046 ASSERT_VK_SUCCESS(err);
7047 // Have to bind memory to image before recording cmd in cmd buffer using it
7048 VkMemoryRequirements mem_reqs;
7049 VkDeviceMemory image_mem;
7051 VkMemoryAllocateInfo mem_alloc = {};
7052 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7053 mem_alloc.pNext = NULL;
7054 mem_alloc.memoryTypeIndex = 0;
7055 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7056 mem_alloc.allocationSize = mem_reqs.size;
7057 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7059 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7060 ASSERT_VK_SUCCESS(err);
7061 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
7062 ASSERT_VK_SUCCESS(err);
7064 m_commandBuffer->BeginCommandBuffer();
7065 VkClearColorValue ccv;
7066 ccv.float32[0] = 1.0f;
7067 ccv.float32[1] = 1.0f;
7068 ccv.float32[2] = 1.0f;
7069 ccv.float32[3] = 1.0f;
7070 VkImageSubresourceRange isr = {};
7071 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7072 isr.baseArrayLayer = 0;
7073 isr.baseMipLevel = 0;
7076 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7077 m_commandBuffer->EndCommandBuffer();
7079 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7080 // Destroy image dependency prior to submit to cause ERROR
7081 vkDestroyImage(m_device->device(), image, NULL);
7083 VkSubmitInfo submit_info = {};
7084 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7085 submit_info.commandBufferCount = 1;
7086 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7087 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7089 m_errorMonitor->VerifyFound();
7090 vkFreeMemory(m_device->device(), image_mem, nullptr);
7093 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
7094 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7095 "due to a framebuffer image dependency being destroyed.");
7096 VkFormatProperties format_properties;
7097 VkResult err = VK_SUCCESS;
7098 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7099 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
7103 ASSERT_NO_FATAL_FAILURE(InitState());
7104 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7106 VkImageCreateInfo image_ci = {};
7107 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7108 image_ci.pNext = NULL;
7109 image_ci.imageType = VK_IMAGE_TYPE_2D;
7110 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7111 image_ci.extent.width = 32;
7112 image_ci.extent.height = 32;
7113 image_ci.extent.depth = 1;
7114 image_ci.mipLevels = 1;
7115 image_ci.arrayLayers = 1;
7116 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7117 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7118 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7119 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7122 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7124 VkMemoryRequirements memory_reqs;
7125 VkDeviceMemory image_memory;
7127 VkMemoryAllocateInfo memory_info = {};
7128 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7129 memory_info.pNext = NULL;
7130 memory_info.allocationSize = 0;
7131 memory_info.memoryTypeIndex = 0;
7132 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7133 memory_info.allocationSize = memory_reqs.size;
7134 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7136 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7137 ASSERT_VK_SUCCESS(err);
7138 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7139 ASSERT_VK_SUCCESS(err);
7141 VkImageViewCreateInfo ivci = {
7142 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7146 VK_IMAGE_VIEW_TYPE_2D,
7147 VK_FORMAT_B8G8R8A8_UNORM,
7148 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7149 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7152 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7153 ASSERT_VK_SUCCESS(err);
7155 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
7157 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7158 ASSERT_VK_SUCCESS(err);
7160 // Just use default renderpass with our framebuffer
7161 m_renderPassBeginInfo.framebuffer = fb;
7162 // Create Null cmd buffer for submit
7163 BeginCommandBuffer();
7165 // Destroy image attached to framebuffer to invalidate cmd buffer
7166 vkDestroyImage(m_device->device(), image, NULL);
7167 // Now attempt to submit cmd buffer and verify error
7168 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7169 QueueCommandBuffer(false);
7170 m_errorMonitor->VerifyFound();
7172 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7173 vkDestroyImageView(m_device->device(), view, nullptr);
7174 vkFreeMemory(m_device->device(), image_memory, nullptr);
7177 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
7178 TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
7179 VkFormatProperties format_properties;
7180 VkResult err = VK_SUCCESS;
7181 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
7183 ASSERT_NO_FATAL_FAILURE(InitState());
7184 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7186 VkImageCreateInfo image_ci = {};
7187 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7188 image_ci.pNext = NULL;
7189 image_ci.imageType = VK_IMAGE_TYPE_2D;
7190 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
7191 image_ci.extent.width = 256;
7192 image_ci.extent.height = 256;
7193 image_ci.extent.depth = 1;
7194 image_ci.mipLevels = 1;
7195 image_ci.arrayLayers = 1;
7196 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
7197 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7198 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
7199 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7202 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
7204 VkMemoryRequirements memory_reqs;
7205 VkDeviceMemory image_memory;
7207 VkMemoryAllocateInfo memory_info = {};
7208 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7209 memory_info.pNext = NULL;
7210 memory_info.allocationSize = 0;
7211 memory_info.memoryTypeIndex = 0;
7212 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7213 memory_info.allocationSize = memory_reqs.size;
7214 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7216 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7217 ASSERT_VK_SUCCESS(err);
7218 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7219 ASSERT_VK_SUCCESS(err);
7221 VkImageViewCreateInfo ivci = {
7222 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7226 VK_IMAGE_VIEW_TYPE_2D,
7227 VK_FORMAT_B8G8R8A8_UNORM,
7228 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
7229 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7232 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7233 ASSERT_VK_SUCCESS(err);
7235 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
7237 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7238 ASSERT_VK_SUCCESS(err);
7240 // Just use default renderpass with our framebuffer
7241 m_renderPassBeginInfo.framebuffer = fb;
7242 // Create Null cmd buffer for submit
7243 BeginCommandBuffer();
7245 // Submit cmd buffer to put it (and attached imageView) in-flight
7246 VkSubmitInfo submit_info = {};
7247 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7248 submit_info.commandBufferCount = 1;
7249 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7250 // Submit cmd buffer to put framebuffer and children in-flight
7251 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7252 // Destroy image attached to framebuffer while in-flight
7253 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
7254 vkDestroyImage(m_device->device(), image, NULL);
7255 m_errorMonitor->VerifyFound();
7256 // Wait for queue to complete so we can safely destroy image and other objects
7257 vkQueueWaitIdle(m_device->m_queue);
7258 vkDestroyImage(m_device->device(), image, NULL);
7259 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7260 vkDestroyImageView(m_device->device(), view, nullptr);
7261 vkFreeMemory(m_device->device(), image_memory, nullptr);
7264 TEST_F(VkLayerTest, ImageMemoryNotBound) {
7265 TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
7266 ASSERT_NO_FATAL_FAILURE(InitState());
7269 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7270 VkImageCreateInfo image_create_info = {};
7271 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7272 image_create_info.pNext = NULL;
7273 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7274 image_create_info.format = tex_format;
7275 image_create_info.extent.width = 32;
7276 image_create_info.extent.height = 32;
7277 image_create_info.extent.depth = 1;
7278 image_create_info.mipLevels = 1;
7279 image_create_info.arrayLayers = 1;
7280 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7281 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7282 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7283 image_create_info.flags = 0;
7284 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7285 ASSERT_VK_SUCCESS(err);
7286 // Have to bind memory to image before recording cmd in cmd buffer using it
7287 VkMemoryRequirements mem_reqs;
7288 VkDeviceMemory image_mem;
7290 VkMemoryAllocateInfo mem_alloc = {};
7291 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7292 mem_alloc.pNext = NULL;
7293 mem_alloc.memoryTypeIndex = 0;
7294 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
7295 mem_alloc.allocationSize = mem_reqs.size;
7296 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
7298 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
7299 ASSERT_VK_SUCCESS(err);
7301 // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
7302 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7303 " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
7305 m_commandBuffer->BeginCommandBuffer();
7306 VkClearColorValue ccv;
7307 ccv.float32[0] = 1.0f;
7308 ccv.float32[1] = 1.0f;
7309 ccv.float32[2] = 1.0f;
7310 ccv.float32[3] = 1.0f;
7311 VkImageSubresourceRange isr = {};
7312 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7313 isr.baseArrayLayer = 0;
7314 isr.baseMipLevel = 0;
7317 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
7318 m_commandBuffer->EndCommandBuffer();
7320 m_errorMonitor->VerifyFound();
7321 vkDestroyImage(m_device->device(), image, NULL);
7322 vkFreeMemory(m_device->device(), image_mem, nullptr);
7325 TEST_F(VkLayerTest, BufferMemoryNotBound) {
7326 TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
7327 ASSERT_NO_FATAL_FAILURE(InitState());
7329 VkImageObj image(m_device);
7330 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7331 VK_IMAGE_TILING_OPTIMAL, 0);
7332 ASSERT_TRUE(image.initialized());
7336 VkMemoryRequirements mem_reqs;
7338 VkBufferCreateInfo buf_info = {};
7339 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7340 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
7341 buf_info.size = 256;
7342 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7343 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
7344 ASSERT_VK_SUCCESS(err);
7346 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
7348 VkMemoryAllocateInfo alloc_info = {};
7349 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7350 alloc_info.allocationSize = 256;
7352 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
7354 vkDestroyBuffer(m_device->device(), buffer, NULL);
7357 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
7358 ASSERT_VK_SUCCESS(err);
7360 // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7361 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7362 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
7363 VkBufferImageCopy region = {};
7364 region.bufferRowLength = 128;
7365 region.bufferImageHeight = 128;
7366 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7368 region.imageSubresource.layerCount = 1;
7369 region.imageExtent.height = 4;
7370 region.imageExtent.width = 4;
7371 region.imageExtent.depth = 1;
7372 m_commandBuffer->BeginCommandBuffer();
7373 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7375 m_commandBuffer->EndCommandBuffer();
7377 m_errorMonitor->VerifyFound();
7379 vkDestroyBuffer(m_device->device(), buffer, NULL);
7380 vkFreeMemory(m_device->handle(), mem, NULL);
7383 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
7384 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7385 "due to an event dependency being destroyed.");
7386 ASSERT_NO_FATAL_FAILURE(InitState());
7389 VkEventCreateInfo evci = {};
7390 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
7391 VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
7392 ASSERT_VK_SUCCESS(result);
7394 m_commandBuffer->BeginCommandBuffer();
7395 vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
7396 m_commandBuffer->EndCommandBuffer();
7398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
7399 // Destroy event dependency prior to submit to cause ERROR
7400 vkDestroyEvent(m_device->device(), event, NULL);
7402 VkSubmitInfo submit_info = {};
7403 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7404 submit_info.commandBufferCount = 1;
7405 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7406 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7408 m_errorMonitor->VerifyFound();
7411 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
7412 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7413 "due to a query pool dependency being destroyed.");
7414 ASSERT_NO_FATAL_FAILURE(InitState());
7416 VkQueryPool query_pool;
7417 VkQueryPoolCreateInfo qpci{};
7418 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7419 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
7420 qpci.queryCount = 1;
7421 VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
7422 ASSERT_VK_SUCCESS(result);
7424 m_commandBuffer->BeginCommandBuffer();
7425 vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
7426 m_commandBuffer->EndCommandBuffer();
7428 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool ");
7429 // Destroy query pool dependency prior to submit to cause ERROR
7430 vkDestroyQueryPool(m_device->device(), query_pool, NULL);
7432 VkSubmitInfo submit_info = {};
7433 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7434 submit_info.commandBufferCount = 1;
7435 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7436 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7438 m_errorMonitor->VerifyFound();
7441 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
7442 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7443 "due to a pipeline dependency being destroyed.");
7444 ASSERT_NO_FATAL_FAILURE(InitState());
7445 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7449 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7450 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7452 VkPipelineLayout pipeline_layout;
7453 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7454 ASSERT_VK_SUCCESS(err);
7456 VkPipelineViewportStateCreateInfo vp_state_ci = {};
7457 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7458 vp_state_ci.viewportCount = 1;
7459 VkViewport vp = {}; // Just need dummy vp to point to
7460 vp_state_ci.pViewports = &vp;
7461 vp_state_ci.scissorCount = 1;
7462 VkRect2D scissors = {}; // Dummy scissors to point to
7463 vp_state_ci.pScissors = &scissors;
7465 VkPipelineShaderStageCreateInfo shaderStages[2];
7466 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
7468 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7469 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
7470 // but add it to be able to run on more devices
7471 shaderStages[0] = vs.GetStageCreateInfo();
7472 shaderStages[1] = fs.GetStageCreateInfo();
7474 VkPipelineVertexInputStateCreateInfo vi_ci = {};
7475 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7477 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
7478 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7479 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
7481 VkPipelineRasterizationStateCreateInfo rs_ci = {};
7482 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7483 rs_ci.rasterizerDiscardEnable = true;
7484 rs_ci.lineWidth = 1.0f;
7486 VkPipelineColorBlendAttachmentState att = {};
7487 att.blendEnable = VK_FALSE;
7488 att.colorWriteMask = 0xf;
7490 VkPipelineColorBlendStateCreateInfo cb_ci = {};
7491 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7492 cb_ci.attachmentCount = 1;
7493 cb_ci.pAttachments = &att;
7495 VkGraphicsPipelineCreateInfo gp_ci = {};
7496 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7497 gp_ci.stageCount = 2;
7498 gp_ci.pStages = shaderStages;
7499 gp_ci.pVertexInputState = &vi_ci;
7500 gp_ci.pInputAssemblyState = &ia_ci;
7501 gp_ci.pViewportState = &vp_state_ci;
7502 gp_ci.pRasterizationState = &rs_ci;
7503 gp_ci.pColorBlendState = &cb_ci;
7504 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
7505 gp_ci.layout = pipeline_layout;
7506 gp_ci.renderPass = renderPass();
7508 VkPipelineCacheCreateInfo pc_ci = {};
7509 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
7511 VkPipeline pipeline;
7512 VkPipelineCache pipelineCache;
7513 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
7514 ASSERT_VK_SUCCESS(err);
7516 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
7517 ASSERT_VK_SUCCESS(err);
7519 m_commandBuffer->BeginCommandBuffer();
7520 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
7521 m_commandBuffer->EndCommandBuffer();
7522 // Now destroy pipeline in order to cause error when submitting
7523 vkDestroyPipeline(m_device->device(), pipeline, nullptr);
7525 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline ");
7527 VkSubmitInfo submit_info = {};
7528 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7529 submit_info.commandBufferCount = 1;
7530 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7531 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7533 m_errorMonitor->VerifyFound();
7534 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
7535 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7538 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
7539 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7540 "due to a bound descriptor set with a buffer dependency "
7541 "being destroyed.");
7542 ASSERT_NO_FATAL_FAILURE(InitState());
7543 ASSERT_NO_FATAL_FAILURE(InitViewport());
7544 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7546 VkDescriptorPoolSize ds_type_count = {};
7547 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7548 ds_type_count.descriptorCount = 1;
7550 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7551 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7552 ds_pool_ci.pNext = NULL;
7553 ds_pool_ci.maxSets = 1;
7554 ds_pool_ci.poolSizeCount = 1;
7555 ds_pool_ci.pPoolSizes = &ds_type_count;
7557 VkDescriptorPool ds_pool;
7558 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7559 ASSERT_VK_SUCCESS(err);
7561 VkDescriptorSetLayoutBinding dsl_binding = {};
7562 dsl_binding.binding = 0;
7563 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7564 dsl_binding.descriptorCount = 1;
7565 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7566 dsl_binding.pImmutableSamplers = NULL;
7568 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7569 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7570 ds_layout_ci.pNext = NULL;
7571 ds_layout_ci.bindingCount = 1;
7572 ds_layout_ci.pBindings = &dsl_binding;
7573 VkDescriptorSetLayout ds_layout;
7574 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7575 ASSERT_VK_SUCCESS(err);
7577 VkDescriptorSet descriptorSet;
7578 VkDescriptorSetAllocateInfo alloc_info = {};
7579 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7580 alloc_info.descriptorSetCount = 1;
7581 alloc_info.descriptorPool = ds_pool;
7582 alloc_info.pSetLayouts = &ds_layout;
7583 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7584 ASSERT_VK_SUCCESS(err);
7586 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7587 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7588 pipeline_layout_ci.pNext = NULL;
7589 pipeline_layout_ci.setLayoutCount = 1;
7590 pipeline_layout_ci.pSetLayouts = &ds_layout;
7592 VkPipelineLayout pipeline_layout;
7593 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7594 ASSERT_VK_SUCCESS(err);
7596 // Create a buffer to update the descriptor with
7598 VkBufferCreateInfo buffCI = {};
7599 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7601 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
7602 buffCI.queueFamilyIndexCount = 1;
7603 buffCI.pQueueFamilyIndices = &qfi;
7606 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
7607 ASSERT_VK_SUCCESS(err);
7608 // Allocate memory and bind to buffer so we can make it to the appropriate
7610 VkMemoryAllocateInfo mem_alloc = {};
7611 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7612 mem_alloc.pNext = NULL;
7613 mem_alloc.allocationSize = 1024;
7614 mem_alloc.memoryTypeIndex = 0;
7616 VkMemoryRequirements memReqs;
7617 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
7618 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
7620 vkDestroyBuffer(m_device->device(), buffer, NULL);
7625 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
7626 ASSERT_VK_SUCCESS(err);
7627 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
7628 ASSERT_VK_SUCCESS(err);
7629 // Correctly update descriptor to avoid "NOT_UPDATED" error
7630 VkDescriptorBufferInfo buffInfo = {};
7631 buffInfo.buffer = buffer;
7632 buffInfo.offset = 0;
7633 buffInfo.range = 1024;
7635 VkWriteDescriptorSet descriptor_write;
7636 memset(&descriptor_write, 0, sizeof(descriptor_write));
7637 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7638 descriptor_write.dstSet = descriptorSet;
7639 descriptor_write.dstBinding = 0;
7640 descriptor_write.descriptorCount = 1;
7641 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
7642 descriptor_write.pBufferInfo = &buffInfo;
7644 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7646 // Create PSO to be used for draw-time errors below
7647 char const *vsSource = "#version 450\n"
7649 "out gl_PerVertex { \n"
7650 " vec4 gl_Position;\n"
7653 " gl_Position = vec4(1);\n"
7655 char const *fsSource = "#version 450\n"
7657 "layout(location=0) out vec4 x;\n"
7658 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
7660 " x = vec4(bar.y);\n"
7662 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7663 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7664 VkPipelineObj pipe(m_device);
7665 pipe.AddShader(&vs);
7666 pipe.AddShader(&fs);
7667 pipe.AddColorAttachment();
7668 pipe.CreateVKPipeline(pipeline_layout, renderPass());
7670 BeginCommandBuffer();
7671 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7672 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7673 &descriptorSet, 0, NULL);
7676 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
7677 // Destroy buffer should invalidate the cmd buffer, causing error on submit
7678 vkDestroyBuffer(m_device->device(), buffer, NULL);
7679 // Attempt to submit cmd buffer
7680 VkSubmitInfo submit_info = {};
7681 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7682 submit_info.commandBufferCount = 1;
7683 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7684 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7685 m_errorMonitor->VerifyFound();
7687 vkFreeMemory(m_device->device(), mem, NULL);
7689 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7690 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7691 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7694 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
7695 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
7696 "due to a bound descriptor sets with a combined image "
7697 "sampler having their image, sampler, and descriptor set "
7698 "each respectively destroyed and then attempting to "
7699 "submit associated cmd buffers. Attempt to destroy a "
7700 "DescriptorSet that is in use.");
7701 ASSERT_NO_FATAL_FAILURE(InitState());
7702 ASSERT_NO_FATAL_FAILURE(InitViewport());
7703 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7705 VkDescriptorPoolSize ds_type_count = {};
7706 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7707 ds_type_count.descriptorCount = 1;
7709 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7710 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7711 ds_pool_ci.pNext = NULL;
7712 ds_pool_ci.maxSets = 1;
7713 ds_pool_ci.poolSizeCount = 1;
7714 ds_pool_ci.pPoolSizes = &ds_type_count;
7716 VkDescriptorPool ds_pool;
7717 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7718 ASSERT_VK_SUCCESS(err);
7720 VkDescriptorSetLayoutBinding dsl_binding = {};
7721 dsl_binding.binding = 0;
7722 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7723 dsl_binding.descriptorCount = 1;
7724 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7725 dsl_binding.pImmutableSamplers = NULL;
7727 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7728 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7729 ds_layout_ci.pNext = NULL;
7730 ds_layout_ci.bindingCount = 1;
7731 ds_layout_ci.pBindings = &dsl_binding;
7732 VkDescriptorSetLayout ds_layout;
7733 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7734 ASSERT_VK_SUCCESS(err);
7736 VkDescriptorSet descriptorSet;
7737 VkDescriptorSetAllocateInfo alloc_info = {};
7738 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7739 alloc_info.descriptorSetCount = 1;
7740 alloc_info.descriptorPool = ds_pool;
7741 alloc_info.pSetLayouts = &ds_layout;
7742 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7743 ASSERT_VK_SUCCESS(err);
7745 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7746 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7747 pipeline_layout_ci.pNext = NULL;
7748 pipeline_layout_ci.setLayoutCount = 1;
7749 pipeline_layout_ci.pSetLayouts = &ds_layout;
7751 VkPipelineLayout pipeline_layout;
7752 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
7753 ASSERT_VK_SUCCESS(err);
7755 // Create images to update the descriptor with
7758 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
7759 const int32_t tex_width = 32;
7760 const int32_t tex_height = 32;
7761 VkImageCreateInfo image_create_info = {};
7762 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7763 image_create_info.pNext = NULL;
7764 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7765 image_create_info.format = tex_format;
7766 image_create_info.extent.width = tex_width;
7767 image_create_info.extent.height = tex_height;
7768 image_create_info.extent.depth = 1;
7769 image_create_info.mipLevels = 1;
7770 image_create_info.arrayLayers = 1;
7771 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7772 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7773 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
7774 image_create_info.flags = 0;
7775 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
7776 ASSERT_VK_SUCCESS(err);
7777 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
7778 ASSERT_VK_SUCCESS(err);
7780 VkMemoryRequirements memory_reqs;
7781 VkDeviceMemory image_memory;
7783 VkMemoryAllocateInfo memory_info = {};
7784 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7785 memory_info.pNext = NULL;
7786 memory_info.allocationSize = 0;
7787 memory_info.memoryTypeIndex = 0;
7788 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
7789 // Allocate enough memory for both images
7790 memory_info.allocationSize = memory_reqs.size * 2;
7791 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
7793 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
7794 ASSERT_VK_SUCCESS(err);
7795 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
7796 ASSERT_VK_SUCCESS(err);
7797 // Bind second image to memory right after first image
7798 err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
7799 ASSERT_VK_SUCCESS(err);
7801 VkImageViewCreateInfo image_view_create_info = {};
7802 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7803 image_view_create_info.image = image;
7804 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
7805 image_view_create_info.format = tex_format;
7806 image_view_create_info.subresourceRange.layerCount = 1;
7807 image_view_create_info.subresourceRange.baseMipLevel = 0;
7808 image_view_create_info.subresourceRange.levelCount = 1;
7809 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7813 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
7814 ASSERT_VK_SUCCESS(err);
7815 image_view_create_info.image = image2;
7816 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
7817 ASSERT_VK_SUCCESS(err);
7819 VkSamplerCreateInfo sampler_ci = {};
7820 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
7821 sampler_ci.pNext = NULL;
7822 sampler_ci.magFilter = VK_FILTER_NEAREST;
7823 sampler_ci.minFilter = VK_FILTER_NEAREST;
7824 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
7825 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7826 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7827 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
7828 sampler_ci.mipLodBias = 1.0;
7829 sampler_ci.anisotropyEnable = VK_FALSE;
7830 sampler_ci.maxAnisotropy = 1;
7831 sampler_ci.compareEnable = VK_FALSE;
7832 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
7833 sampler_ci.minLod = 1.0;
7834 sampler_ci.maxLod = 1.0;
7835 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
7836 sampler_ci.unnormalizedCoordinates = VK_FALSE;
7839 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7840 ASSERT_VK_SUCCESS(err);
7841 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
7842 ASSERT_VK_SUCCESS(err);
7843 // Update descriptor with image and sampler
7844 VkDescriptorImageInfo img_info = {};
7845 img_info.sampler = sampler;
7846 img_info.imageView = view;
7847 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7849 VkWriteDescriptorSet descriptor_write;
7850 memset(&descriptor_write, 0, sizeof(descriptor_write));
7851 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
7852 descriptor_write.dstSet = descriptorSet;
7853 descriptor_write.dstBinding = 0;
7854 descriptor_write.descriptorCount = 1;
7855 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7856 descriptor_write.pImageInfo = &img_info;
7858 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7860 // Create PSO to be used for draw-time errors below
7861 char const *vsSource = "#version 450\n"
7863 "out gl_PerVertex { \n"
7864 " vec4 gl_Position;\n"
7867 " gl_Position = vec4(1);\n"
7869 char const *fsSource = "#version 450\n"
7871 "layout(set=0, binding=0) uniform sampler2D s;\n"
7872 "layout(location=0) out vec4 x;\n"
7874 " x = texture(s, vec2(1));\n"
7876 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
7877 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7878 VkPipelineObj pipe(m_device);
7879 pipe.AddShader(&vs);
7880 pipe.AddShader(&fs);
7881 pipe.AddColorAttachment();
7882 pipe.CreateVKPipeline(pipeline_layout, renderPass());
7884 // First error case is destroying sampler prior to cmd buffer submission
7885 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler ");
7886 BeginCommandBuffer();
7887 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7888 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7889 &descriptorSet, 0, NULL);
7892 // Destroy sampler invalidates the cmd buffer, causing error on submit
7893 vkDestroySampler(m_device->device(), sampler, NULL);
7894 // Attempt to submit cmd buffer
7895 VkSubmitInfo submit_info = {};
7896 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7897 submit_info.commandBufferCount = 1;
7898 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7899 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7900 m_errorMonitor->VerifyFound();
7901 // Now re-update descriptor with valid sampler and delete image
7902 img_info.sampler = sampler2;
7903 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7904 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
7905 BeginCommandBuffer();
7906 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7907 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7908 &descriptorSet, 0, NULL);
7911 // Destroy image invalidates the cmd buffer, causing error on submit
7912 vkDestroyImage(m_device->device(), image, NULL);
7913 // Attempt to submit cmd buffer
7915 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7916 submit_info.commandBufferCount = 1;
7917 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7918 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7919 m_errorMonitor->VerifyFound();
7920 // Now update descriptor to be valid, but then free descriptor
7921 img_info.imageView = view2;
7922 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
7923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set ");
7924 BeginCommandBuffer();
7925 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7926 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
7927 &descriptorSet, 0, NULL);
7930 // Destroy descriptor set invalidates the cb, causing error on submit
7931 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
7932 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
7933 m_errorMonitor->VerifyFound();
7934 // Attempt to submit cmd buffer
7936 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7937 submit_info.commandBufferCount = 1;
7938 submit_info.pCommandBuffers = &m_commandBuffer->handle();
7939 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7940 m_errorMonitor->VerifyFound();
7942 vkFreeMemory(m_device->device(), image_memory, NULL);
7943 vkDestroySampler(m_device->device(), sampler2, NULL);
7944 vkDestroyImage(m_device->device(), image2, NULL);
7945 vkDestroyImageView(m_device->device(), view, NULL);
7946 vkDestroyImageView(m_device->device(), view2, NULL);
7947 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
7948 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
7949 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
7952 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
7953 TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
7954 ASSERT_NO_FATAL_FAILURE(InitState());
7955 ASSERT_NO_FATAL_FAILURE(InitViewport());
7956 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7958 VkDescriptorPoolSize ds_type_count = {};
7959 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7960 ds_type_count.descriptorCount = 1;
7962 VkDescriptorPoolCreateInfo ds_pool_ci = {};
7963 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
7964 ds_pool_ci.pNext = NULL;
7965 ds_pool_ci.maxSets = 1;
7966 ds_pool_ci.poolSizeCount = 1;
7967 ds_pool_ci.pPoolSizes = &ds_type_count;
7969 VkDescriptorPool ds_pool;
7970 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
7971 ASSERT_VK_SUCCESS(err);
7973 VkDescriptorSetLayoutBinding dsl_binding = {};
7974 dsl_binding.binding = 0;
7975 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
7976 dsl_binding.descriptorCount = 1;
7977 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
7978 dsl_binding.pImmutableSamplers = NULL;
7980 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
7981 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
7982 ds_layout_ci.pNext = NULL;
7983 ds_layout_ci.bindingCount = 1;
7984 ds_layout_ci.pBindings = &dsl_binding;
7985 VkDescriptorSetLayout ds_layout;
7986 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
7987 ASSERT_VK_SUCCESS(err);
7989 VkDescriptorSet descriptorSet;
7990 VkDescriptorSetAllocateInfo alloc_info = {};
7991 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7992 alloc_info.descriptorSetCount = 1;
7993 alloc_info.descriptorPool = ds_pool;
7994 alloc_info.pSetLayouts = &ds_layout;
7995 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
7996 ASSERT_VK_SUCCESS(err);
7998 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
7999 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8000 pipeline_layout_ci.pNext = NULL;
8001 pipeline_layout_ci.setLayoutCount = 1;
8002 pipeline_layout_ci.pSetLayouts = &ds_layout;
8004 VkPipelineLayout pipeline_layout;
8005 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8006 ASSERT_VK_SUCCESS(err);
8008 // Create images to update the descriptor with
8010 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8011 const int32_t tex_width = 32;
8012 const int32_t tex_height = 32;
8013 VkImageCreateInfo image_create_info = {};
8014 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8015 image_create_info.pNext = NULL;
8016 image_create_info.imageType = VK_IMAGE_TYPE_2D;
8017 image_create_info.format = tex_format;
8018 image_create_info.extent.width = tex_width;
8019 image_create_info.extent.height = tex_height;
8020 image_create_info.extent.depth = 1;
8021 image_create_info.mipLevels = 1;
8022 image_create_info.arrayLayers = 1;
8023 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
8024 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
8025 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8026 image_create_info.flags = 0;
8027 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
8028 ASSERT_VK_SUCCESS(err);
8029 // Initially bind memory to avoid error at bind view time. We'll break binding before update.
8030 VkMemoryRequirements memory_reqs;
8031 VkDeviceMemory image_memory;
8033 VkMemoryAllocateInfo memory_info = {};
8034 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8035 memory_info.pNext = NULL;
8036 memory_info.allocationSize = 0;
8037 memory_info.memoryTypeIndex = 0;
8038 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
8039 // Allocate enough memory for image
8040 memory_info.allocationSize = memory_reqs.size;
8041 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
8043 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
8044 ASSERT_VK_SUCCESS(err);
8045 err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
8046 ASSERT_VK_SUCCESS(err);
8048 VkImageViewCreateInfo image_view_create_info = {};
8049 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8050 image_view_create_info.image = image;
8051 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
8052 image_view_create_info.format = tex_format;
8053 image_view_create_info.subresourceRange.layerCount = 1;
8054 image_view_create_info.subresourceRange.baseMipLevel = 0;
8055 image_view_create_info.subresourceRange.levelCount = 1;
8056 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8059 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
8060 ASSERT_VK_SUCCESS(err);
8062 VkSamplerCreateInfo sampler_ci = {};
8063 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
8064 sampler_ci.pNext = NULL;
8065 sampler_ci.magFilter = VK_FILTER_NEAREST;
8066 sampler_ci.minFilter = VK_FILTER_NEAREST;
8067 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
8068 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8069 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8070 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
8071 sampler_ci.mipLodBias = 1.0;
8072 sampler_ci.anisotropyEnable = VK_FALSE;
8073 sampler_ci.maxAnisotropy = 1;
8074 sampler_ci.compareEnable = VK_FALSE;
8075 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
8076 sampler_ci.minLod = 1.0;
8077 sampler_ci.maxLod = 1.0;
8078 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
8079 sampler_ci.unnormalizedCoordinates = VK_FALSE;
8081 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8082 ASSERT_VK_SUCCESS(err);
8083 // Update descriptor with image and sampler
8084 VkDescriptorImageInfo img_info = {};
8085 img_info.sampler = sampler;
8086 img_info.imageView = view;
8087 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8089 VkWriteDescriptorSet descriptor_write;
8090 memset(&descriptor_write, 0, sizeof(descriptor_write));
8091 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8092 descriptor_write.dstSet = descriptorSet;
8093 descriptor_write.dstBinding = 0;
8094 descriptor_write.descriptorCount = 1;
8095 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8096 descriptor_write.pImageInfo = &img_info;
8097 // Break memory binding and attempt update
8098 vkFreeMemory(m_device->device(), image_memory, nullptr);
8099 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8100 " previously bound memory was freed. Memory must not be freed prior to this operation.");
8101 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8102 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8103 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8104 m_errorMonitor->VerifyFound();
8106 vkDestroyImage(m_device->device(), image, NULL);
8107 vkDestroySampler(m_device->device(), sampler, NULL);
8108 vkDestroyImageView(m_device->device(), view, NULL);
8109 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8110 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8111 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8114 TEST_F(VkLayerTest, InvalidPipeline) {
8115 // Attempt to bind an invalid Pipeline to a valid Command Buffer
8116 // ObjectTracker should catch this.
8117 // Create a valid cmd buffer
8118 // call vkCmdBindPipeline w/ false Pipeline
8119 uint64_t fake_pipeline_handle = 0xbaad6001;
8120 VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
8121 ASSERT_NO_FATAL_FAILURE(InitState());
8122 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8124 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
8125 BeginCommandBuffer();
8126 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
8127 m_errorMonitor->VerifyFound();
8129 // Now issue a draw call with no pipeline bound
8130 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8132 m_errorMonitor->VerifyFound();
8134 // Finally same check once more but with Dispatch/Compute
8135 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
8136 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
8137 vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
8138 m_errorMonitor->VerifyFound();
8141 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
8142 TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
8145 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
8147 ASSERT_NO_FATAL_FAILURE(InitState());
8148 ASSERT_NO_FATAL_FAILURE(InitViewport());
8149 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8150 VkDescriptorPoolSize ds_type_count = {};
8151 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8152 ds_type_count.descriptorCount = 1;
8154 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8155 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8156 ds_pool_ci.pNext = NULL;
8157 ds_pool_ci.maxSets = 1;
8158 ds_pool_ci.poolSizeCount = 1;
8159 ds_pool_ci.pPoolSizes = &ds_type_count;
8161 VkDescriptorPool ds_pool;
8162 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8163 ASSERT_VK_SUCCESS(err);
8165 VkDescriptorSetLayoutBinding dsl_binding = {};
8166 dsl_binding.binding = 0;
8167 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8168 dsl_binding.descriptorCount = 1;
8169 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8170 dsl_binding.pImmutableSamplers = NULL;
8172 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8173 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8174 ds_layout_ci.pNext = NULL;
8175 ds_layout_ci.bindingCount = 1;
8176 ds_layout_ci.pBindings = &dsl_binding;
8177 VkDescriptorSetLayout ds_layout;
8178 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8179 ASSERT_VK_SUCCESS(err);
8181 VkDescriptorSet descriptorSet;
8182 VkDescriptorSetAllocateInfo alloc_info = {};
8183 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8184 alloc_info.descriptorSetCount = 1;
8185 alloc_info.descriptorPool = ds_pool;
8186 alloc_info.pSetLayouts = &ds_layout;
8187 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8188 ASSERT_VK_SUCCESS(err);
8190 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8191 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8192 pipeline_layout_ci.pNext = NULL;
8193 pipeline_layout_ci.setLayoutCount = 1;
8194 pipeline_layout_ci.pSetLayouts = &ds_layout;
8196 VkPipelineLayout pipeline_layout;
8197 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8198 ASSERT_VK_SUCCESS(err);
8200 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8201 // We shouldn't need a fragment shader but add it to be able to run
8203 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8205 VkPipelineObj pipe(m_device);
8206 pipe.AddShader(&vs);
8207 pipe.AddShader(&fs);
8208 pipe.AddColorAttachment();
8209 pipe.CreateVKPipeline(pipeline_layout, renderPass());
8211 BeginCommandBuffer();
8212 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8213 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8214 &descriptorSet, 0, NULL);
8216 m_errorMonitor->VerifyFound();
8218 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8219 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8220 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8223 TEST_F(VkLayerTest, InvalidBufferViewObject) {
8224 // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
8227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer "
8228 "descriptor with invalid buffer view");
8230 ASSERT_NO_FATAL_FAILURE(InitState());
8231 VkDescriptorPoolSize ds_type_count = {};
8232 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8233 ds_type_count.descriptorCount = 1;
8235 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8236 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8237 ds_pool_ci.pNext = NULL;
8238 ds_pool_ci.maxSets = 1;
8239 ds_pool_ci.poolSizeCount = 1;
8240 ds_pool_ci.pPoolSizes = &ds_type_count;
8242 VkDescriptorPool ds_pool;
8243 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8244 ASSERT_VK_SUCCESS(err);
8246 VkDescriptorSetLayoutBinding dsl_binding = {};
8247 dsl_binding.binding = 0;
8248 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8249 dsl_binding.descriptorCount = 1;
8250 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8251 dsl_binding.pImmutableSamplers = NULL;
8253 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8254 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8255 ds_layout_ci.pNext = NULL;
8256 ds_layout_ci.bindingCount = 1;
8257 ds_layout_ci.pBindings = &dsl_binding;
8258 VkDescriptorSetLayout ds_layout;
8259 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8260 ASSERT_VK_SUCCESS(err);
8262 VkDescriptorSet descriptorSet;
8263 VkDescriptorSetAllocateInfo alloc_info = {};
8264 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8265 alloc_info.descriptorSetCount = 1;
8266 alloc_info.descriptorPool = ds_pool;
8267 alloc_info.pSetLayouts = &ds_layout;
8268 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8269 ASSERT_VK_SUCCESS(err);
8271 VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object
8272 VkWriteDescriptorSet descriptor_write;
8273 memset(&descriptor_write, 0, sizeof(descriptor_write));
8274 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8275 descriptor_write.dstSet = descriptorSet;
8276 descriptor_write.dstBinding = 0;
8277 descriptor_write.descriptorCount = 1;
8278 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
8279 descriptor_write.pTexelBufferView = &view;
8281 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8283 m_errorMonitor->VerifyFound();
8285 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8286 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8289 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
8290 TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
8293 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8294 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8296 ASSERT_NO_FATAL_FAILURE(InitState());
8298 // Create a buffer with no bound memory and then attempt to create
8300 VkBufferCreateInfo buff_ci = {};
8301 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8302 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
8304 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8306 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
8307 ASSERT_VK_SUCCESS(err);
8309 VkBufferViewCreateInfo buff_view_ci = {};
8310 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8311 buff_view_ci.buffer = buffer;
8312 buff_view_ci.format = VK_FORMAT_R8_UNORM;
8313 buff_view_ci.range = VK_WHOLE_SIZE;
8314 VkBufferView buff_view;
8315 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
8317 m_errorMonitor->VerifyFound();
8318 vkDestroyBuffer(m_device->device(), buffer, NULL);
8319 // If last error is success, it still created the view, so delete it.
8320 if (err == VK_SUCCESS) {
8321 vkDestroyBufferView(m_device->device(), buff_view, NULL);
8325 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
8326 // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
8328 // 1. No dynamicOffset supplied
8329 // 2. Too many dynamicOffsets supplied
8330 // 3. Dynamic offset oversteps buffer being updated
8332 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only "
8333 "0 dynamicOffsets are left in "
8334 "pDynamicOffsets ");
8336 ASSERT_NO_FATAL_FAILURE(InitState());
8337 ASSERT_NO_FATAL_FAILURE(InitViewport());
8338 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8340 VkDescriptorPoolSize ds_type_count = {};
8341 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8342 ds_type_count.descriptorCount = 1;
8344 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8345 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8346 ds_pool_ci.pNext = NULL;
8347 ds_pool_ci.maxSets = 1;
8348 ds_pool_ci.poolSizeCount = 1;
8349 ds_pool_ci.pPoolSizes = &ds_type_count;
8351 VkDescriptorPool ds_pool;
8352 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8353 ASSERT_VK_SUCCESS(err);
8355 VkDescriptorSetLayoutBinding dsl_binding = {};
8356 dsl_binding.binding = 0;
8357 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8358 dsl_binding.descriptorCount = 1;
8359 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8360 dsl_binding.pImmutableSamplers = NULL;
8362 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8363 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8364 ds_layout_ci.pNext = NULL;
8365 ds_layout_ci.bindingCount = 1;
8366 ds_layout_ci.pBindings = &dsl_binding;
8367 VkDescriptorSetLayout ds_layout;
8368 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8369 ASSERT_VK_SUCCESS(err);
8371 VkDescriptorSet descriptorSet;
8372 VkDescriptorSetAllocateInfo alloc_info = {};
8373 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8374 alloc_info.descriptorSetCount = 1;
8375 alloc_info.descriptorPool = ds_pool;
8376 alloc_info.pSetLayouts = &ds_layout;
8377 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8378 ASSERT_VK_SUCCESS(err);
8380 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8381 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8382 pipeline_layout_ci.pNext = NULL;
8383 pipeline_layout_ci.setLayoutCount = 1;
8384 pipeline_layout_ci.pSetLayouts = &ds_layout;
8386 VkPipelineLayout pipeline_layout;
8387 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8388 ASSERT_VK_SUCCESS(err);
8390 // Create a buffer to update the descriptor with
8392 VkBufferCreateInfo buffCI = {};
8393 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8395 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8396 buffCI.queueFamilyIndexCount = 1;
8397 buffCI.pQueueFamilyIndices = &qfi;
8400 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8401 ASSERT_VK_SUCCESS(err);
8402 // Allocate memory and bind to buffer so we can make it to the appropriate
8404 VkMemoryAllocateInfo mem_alloc = {};
8405 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8406 mem_alloc.pNext = NULL;
8407 mem_alloc.allocationSize = 1024;
8408 mem_alloc.memoryTypeIndex = 0;
8410 VkMemoryRequirements memReqs;
8411 vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
8412 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
8414 vkDestroyBuffer(m_device->device(), dyub, NULL);
8419 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
8420 ASSERT_VK_SUCCESS(err);
8421 err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8422 ASSERT_VK_SUCCESS(err);
8423 // Correctly update descriptor to avoid "NOT_UPDATED" error
8424 VkDescriptorBufferInfo buffInfo = {};
8425 buffInfo.buffer = dyub;
8426 buffInfo.offset = 0;
8427 buffInfo.range = 1024;
8429 VkWriteDescriptorSet descriptor_write;
8430 memset(&descriptor_write, 0, sizeof(descriptor_write));
8431 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8432 descriptor_write.dstSet = descriptorSet;
8433 descriptor_write.dstBinding = 0;
8434 descriptor_write.descriptorCount = 1;
8435 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8436 descriptor_write.pBufferInfo = &buffInfo;
8438 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8440 BeginCommandBuffer();
8441 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8442 &descriptorSet, 0, NULL);
8443 m_errorMonitor->VerifyFound();
8444 uint32_t pDynOff[2] = {512, 756};
8445 // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
8446 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8447 "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
8448 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8449 &descriptorSet, 2, pDynOff);
8450 m_errorMonitor->VerifyFound();
8451 // Finally cause error due to dynamicOffset being too big
8452 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with "
8453 "offset 0 and range 1024 that "
8454 "oversteps the buffer size of 1024");
8455 // Create PSO to be used for draw-time errors below
8456 char const *vsSource = "#version 450\n"
8458 "out gl_PerVertex { \n"
8459 " vec4 gl_Position;\n"
8462 " gl_Position = vec4(1);\n"
8464 char const *fsSource = "#version 450\n"
8466 "layout(location=0) out vec4 x;\n"
8467 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8469 " x = vec4(bar.y);\n"
8471 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8472 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8473 VkPipelineObj pipe(m_device);
8474 pipe.AddShader(&vs);
8475 pipe.AddShader(&fs);
8476 pipe.AddColorAttachment();
8477 pipe.CreateVKPipeline(pipeline_layout, renderPass());
8479 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8480 // This update should succeed, but offset size of 512 will overstep buffer
8481 // /w range 1024 & size 1024
8482 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
8483 &descriptorSet, 1, pDynOff);
8485 m_errorMonitor->VerifyFound();
8487 vkDestroyBuffer(m_device->device(), dyub, NULL);
8488 vkFreeMemory(m_device->device(), mem, NULL);
8490 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8491 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8492 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8495 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
8496 TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
8497 "that doesn't have memory bound");
8499 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8500 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
8501 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8502 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
8504 ASSERT_NO_FATAL_FAILURE(InitState());
8505 ASSERT_NO_FATAL_FAILURE(InitViewport());
8506 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8508 VkDescriptorPoolSize ds_type_count = {};
8509 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8510 ds_type_count.descriptorCount = 1;
8512 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8513 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8514 ds_pool_ci.pNext = NULL;
8515 ds_pool_ci.maxSets = 1;
8516 ds_pool_ci.poolSizeCount = 1;
8517 ds_pool_ci.pPoolSizes = &ds_type_count;
8519 VkDescriptorPool ds_pool;
8520 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8521 ASSERT_VK_SUCCESS(err);
8523 VkDescriptorSetLayoutBinding dsl_binding = {};
8524 dsl_binding.binding = 0;
8525 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8526 dsl_binding.descriptorCount = 1;
8527 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8528 dsl_binding.pImmutableSamplers = NULL;
8530 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8531 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8532 ds_layout_ci.pNext = NULL;
8533 ds_layout_ci.bindingCount = 1;
8534 ds_layout_ci.pBindings = &dsl_binding;
8535 VkDescriptorSetLayout ds_layout;
8536 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8537 ASSERT_VK_SUCCESS(err);
8539 VkDescriptorSet descriptorSet;
8540 VkDescriptorSetAllocateInfo alloc_info = {};
8541 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8542 alloc_info.descriptorSetCount = 1;
8543 alloc_info.descriptorPool = ds_pool;
8544 alloc_info.pSetLayouts = &ds_layout;
8545 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8546 ASSERT_VK_SUCCESS(err);
8548 // Create a buffer to update the descriptor with
8550 VkBufferCreateInfo buffCI = {};
8551 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8553 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8554 buffCI.queueFamilyIndexCount = 1;
8555 buffCI.pQueueFamilyIndices = &qfi;
8558 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8559 ASSERT_VK_SUCCESS(err);
8561 // Attempt to update descriptor without binding memory to it
8562 VkDescriptorBufferInfo buffInfo = {};
8563 buffInfo.buffer = dyub;
8564 buffInfo.offset = 0;
8565 buffInfo.range = 1024;
8567 VkWriteDescriptorSet descriptor_write;
8568 memset(&descriptor_write, 0, sizeof(descriptor_write));
8569 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8570 descriptor_write.dstSet = descriptorSet;
8571 descriptor_write.dstBinding = 0;
8572 descriptor_write.descriptorCount = 1;
8573 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
8574 descriptor_write.pBufferInfo = &buffInfo;
8576 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8577 m_errorMonitor->VerifyFound();
8579 vkDestroyBuffer(m_device->device(), dyub, NULL);
8580 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8581 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8584 TEST_F(VkLayerTest, InvalidPushConstants) {
8586 ASSERT_NO_FATAL_FAILURE(InitState());
8587 ASSERT_NO_FATAL_FAILURE(InitViewport());
8588 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8590 VkPipelineLayout pipeline_layout;
8591 VkPushConstantRange pc_range = {};
8592 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8593 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8594 pipeline_layout_ci.pushConstantRangeCount = 1;
8595 pipeline_layout_ci.pPushConstantRanges = &pc_range;
8598 // Check for invalid push constant ranges in pipeline layouts.
8600 struct PipelineLayoutTestCase {
8601 VkPushConstantRange const range;
8605 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
8606 const std::array<PipelineLayoutTestCase, 10> range_tests = {{
8607 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
8608 "vkCreatePipelineLayout() call has push constants index 0 with "
8610 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8611 "vkCreatePipelineLayout() call has push constants index 0 with "
8613 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8614 "vkCreatePipelineLayout() call has push constants index 0 with "
8616 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
8617 "vkCreatePipelineLayout() call has push constants index 0 with "
8619 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8620 "vkCreatePipelineLayout() call has push constants index 0 with "
8621 "offset 1. Offset must"},
8622 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big},
8623 "vkCreatePipelineLayout() call has push constants index 0 "
8625 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
8626 "vkCreatePipelineLayout() call has push constants "
8627 "index 0 with offset "},
8628 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
8629 "vkCreatePipelineLayout() call has push constants index 0 "
8631 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
8632 "vkCreatePipelineLayout() call has push "
8633 "constants index 0 with offset "},
8634 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
8635 "vkCreatePipelineLayout() call has push "
8636 "constants index 0 with offset "},
8639 // Check for invalid offset and size
8640 for (const auto &iter : range_tests) {
8641 pc_range = iter.range;
8642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8643 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8644 m_errorMonitor->VerifyFound();
8645 if (VK_SUCCESS == err) {
8646 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8650 // Check for invalid stage flag
8651 pc_range.offset = 0;
8653 pc_range.stageFlags = 0;
8654 m_errorMonitor->SetDesiredFailureMsg(
8655 VK_DEBUG_REPORT_ERROR_BIT_EXT,
8656 "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
8657 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8658 m_errorMonitor->VerifyFound();
8659 if (VK_SUCCESS == err) {
8660 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8663 // Check for overlapping ranges
8664 const uint32_t ranges_per_test = 5;
8665 struct OverlappingRangeTestCase {
8666 VkPushConstantRange const ranges[ranges_per_test];
8670 const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = {
8671 {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8672 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8673 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8674 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8675 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8676 "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
8678 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8679 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8680 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8681 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8682 {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8683 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
8686 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8687 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8688 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8689 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8690 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8691 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
8694 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8695 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8696 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8697 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
8698 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8699 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
8702 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8703 {VK_SHADER_STAGE_VERTEX_BIT, 32, 4},
8704 {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
8705 {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
8706 {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
8707 "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
8710 for (const auto &iter : overlapping_range_tests) {
8711 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8712 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
8713 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg);
8714 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8715 m_errorMonitor->VerifyFound();
8716 if (VK_SUCCESS == err) {
8717 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8721 // Run some positive tests to make sure overlap checking in the layer is OK
8722 const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
8723 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
8724 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
8725 {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
8726 {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
8728 {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
8729 {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
8730 {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
8731 {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
8732 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
8734 for (const auto &iter : overlapping_range_tests_pos) {
8735 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
8736 m_errorMonitor->ExpectSuccess();
8737 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8738 m_errorMonitor->VerifyNotFound();
8739 if (VK_SUCCESS == err) {
8740 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8745 // CmdPushConstants tests
8747 const uint8_t dummy_values[100] = {};
8749 // Check for invalid offset and size and if range is within layout range(s)
8750 const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
8751 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
8752 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
8753 "vkCmdPushConstants() call has push constants with size 1. Size "
8754 "must be greater than zero and a multiple of 4."},
8755 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
8756 "vkCmdPushConstants() call has push constants with size 1. Size "
8757 "must be greater than zero and a multiple of 4."},
8758 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8759 "vkCmdPushConstants() call has push constants with offset 1. "
8760 "Offset must be a multiple of 4."},
8761 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
8762 "vkCmdPushConstants() call has push constants with offset 1. "
8763 "Offset must be a multiple of 4."},
8764 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8765 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8766 "0x1 not within flag-matching ranges in pipeline layout"},
8767 {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8},
8768 "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = "
8769 "0x1 not within flag-matching ranges in pipeline layout"},
8770 {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8},
8771 "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = "
8772 "0x1 not within flag-matching ranges in pipeline layout"},
8773 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80},
8774 "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = "
8775 "0x1 not within flag-matching ranges in pipeline layout"},
8776 {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
8777 "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in "
8778 "any of the ranges in pipeline layout"},
8779 {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
8780 "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
8781 "any of the ranges in pipeline layout"},
8784 BeginCommandBuffer();
8786 // Setup ranges: [0,16) [64,80)
8787 const VkPushConstantRange pc_range2[] = {
8788 {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
8790 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange);
8791 pipeline_layout_ci.pPushConstantRanges = pc_range2;
8792 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8793 ASSERT_VK_SUCCESS(err);
8794 for (const auto &iter : cmd_range_tests) {
8795 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8796 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8797 iter.range.size, dummy_values);
8798 m_errorMonitor->VerifyFound();
8801 // Check for invalid stage flag
8802 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
8803 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
8804 m_errorMonitor->VerifyFound();
8805 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8807 // overlapping range tests with cmd
8808 const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{
8809 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20},
8810 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = "
8811 "0x1 not within flag-matching ranges in pipeline layout"},
8812 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
8813 "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = "
8814 "0x1 not within flag-matching ranges in pipeline layout"},
8815 {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16},
8816 "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
8817 "0x1 not within flag-matching ranges in pipeline layout"},
8819 // Setup ranges: [0,16), [20,36), [36,44), [44,52), [80,92)
8820 const VkPushConstantRange pc_range3[] = {
8821 {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8822 {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
8824 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
8825 pipeline_layout_ci.pPushConstantRanges = pc_range3;
8826 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8827 ASSERT_VK_SUCCESS(err);
8828 for (const auto &iter : cmd_overlap_tests) {
8829 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
8830 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8831 iter.range.size, dummy_values);
8832 m_errorMonitor->VerifyFound();
8834 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8836 // positive overlapping range tests with cmd
8837 const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
8838 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
8839 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
8840 {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
8841 {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
8843 // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
8844 const VkPushConstantRange pc_range4[] = {
8845 {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
8846 {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 24},
8848 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
8849 pipeline_layout_ci.pPushConstantRanges = pc_range4;
8850 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8851 ASSERT_VK_SUCCESS(err);
8852 for (const auto &iter : cmd_overlap_tests_pos) {
8853 m_errorMonitor->ExpectSuccess();
8854 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
8855 iter.range.size, dummy_values);
8856 m_errorMonitor->VerifyNotFound();
8858 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
8863 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
8864 // Test various desriptorSet errors with bad binding combinations
8867 ASSERT_NO_FATAL_FAILURE(InitState());
8868 ASSERT_NO_FATAL_FAILURE(InitViewport());
8869 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8871 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
8872 VkImageTiling tiling;
8873 VkFormatProperties format_properties;
8874 vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
8875 if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8876 tiling = VK_IMAGE_TILING_LINEAR;
8877 } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
8878 tiling = VK_IMAGE_TILING_OPTIMAL;
8880 printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
8885 static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
8886 VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
8887 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8888 ds_type_count[0].descriptorCount = 10;
8889 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8890 ds_type_count[1].descriptorCount = 2;
8891 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8892 ds_type_count[2].descriptorCount = 2;
8893 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
8894 ds_type_count[3].descriptorCount = 5;
8895 // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
8897 // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
8898 ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8899 ds_type_count[4].descriptorCount = 2;
8901 VkDescriptorPoolCreateInfo ds_pool_ci = {};
8902 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8903 ds_pool_ci.pNext = NULL;
8904 ds_pool_ci.maxSets = 5;
8905 ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
8906 ds_pool_ci.pPoolSizes = ds_type_count;
8908 VkDescriptorPool ds_pool;
8909 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8910 ASSERT_VK_SUCCESS(err);
8912 static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
8913 VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
8914 dsl_binding[0].binding = 0;
8915 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8916 dsl_binding[0].descriptorCount = 5;
8917 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
8918 dsl_binding[0].pImmutableSamplers = NULL;
8920 // Create layout identical to set0 layout but w/ different stageFlags
8921 VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
8922 dsl_fs_stage_only.binding = 0;
8923 dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8924 dsl_fs_stage_only.descriptorCount = 5;
8925 dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at
8927 dsl_fs_stage_only.pImmutableSamplers = NULL;
8928 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8929 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8930 ds_layout_ci.pNext = NULL;
8931 ds_layout_ci.bindingCount = 1;
8932 ds_layout_ci.pBindings = dsl_binding;
8933 static const uint32_t NUM_LAYOUTS = 4;
8934 VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {};
8935 VkDescriptorSetLayout ds_layout_fs_only = {};
8936 // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
8937 // layout for error case
8938 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]);
8939 ASSERT_VK_SUCCESS(err);
8940 ds_layout_ci.pBindings = &dsl_fs_stage_only;
8941 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only);
8942 ASSERT_VK_SUCCESS(err);
8943 dsl_binding[0].binding = 0;
8944 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8945 dsl_binding[0].descriptorCount = 2;
8946 dsl_binding[1].binding = 1;
8947 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
8948 dsl_binding[1].descriptorCount = 2;
8949 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
8950 dsl_binding[1].pImmutableSamplers = NULL;
8951 ds_layout_ci.pBindings = dsl_binding;
8952 ds_layout_ci.bindingCount = 2;
8953 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]);
8954 ASSERT_VK_SUCCESS(err);
8955 dsl_binding[0].binding = 0;
8956 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8957 dsl_binding[0].descriptorCount = 5;
8958 ds_layout_ci.bindingCount = 1;
8959 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]);
8960 ASSERT_VK_SUCCESS(err);
8961 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
8962 dsl_binding[0].descriptorCount = 2;
8963 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]);
8964 ASSERT_VK_SUCCESS(err);
8966 static const uint32_t NUM_SETS = 4;
8967 VkDescriptorSet descriptorSet[NUM_SETS] = {};
8968 VkDescriptorSetAllocateInfo alloc_info = {};
8969 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8970 alloc_info.descriptorSetCount = NUM_LAYOUTS;
8971 alloc_info.descriptorPool = ds_pool;
8972 alloc_info.pSetLayouts = ds_layout;
8973 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
8974 ASSERT_VK_SUCCESS(err);
8975 VkDescriptorSet ds0_fs_only = {};
8976 alloc_info.descriptorSetCount = 1;
8977 alloc_info.pSetLayouts = &ds_layout_fs_only;
8978 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
8979 ASSERT_VK_SUCCESS(err);
8981 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8982 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8983 pipeline_layout_ci.pNext = NULL;
8984 pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS;
8985 pipeline_layout_ci.pSetLayouts = ds_layout;
8987 VkPipelineLayout pipeline_layout;
8988 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8989 ASSERT_VK_SUCCESS(err);
8990 // Create pipelineLayout with only one setLayout
8991 pipeline_layout_ci.setLayoutCount = 1;
8992 VkPipelineLayout single_pipe_layout;
8993 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout);
8994 ASSERT_VK_SUCCESS(err);
8995 // Create pipelineLayout with 2 descriptor setLayout at index 0
8996 pipeline_layout_ci.pSetLayouts = &ds_layout[3];
8997 VkPipelineLayout pipe_layout_one_desc;
8998 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc);
8999 ASSERT_VK_SUCCESS(err);
9000 // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
9001 pipeline_layout_ci.pSetLayouts = &ds_layout[2];
9002 VkPipelineLayout pipe_layout_five_samp;
9003 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp);
9004 ASSERT_VK_SUCCESS(err);
9005 // Create pipelineLayout with UB type, but stageFlags for FS only
9006 pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only;
9007 VkPipelineLayout pipe_layout_fs_only;
9008 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only);
9009 ASSERT_VK_SUCCESS(err);
9010 // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
9011 VkDescriptorSetLayout pl_bad_s0[2] = {};
9012 pl_bad_s0[0] = ds_layout_fs_only;
9013 pl_bad_s0[1] = ds_layout[1];
9014 pipeline_layout_ci.setLayoutCount = 2;
9015 pipeline_layout_ci.pSetLayouts = pl_bad_s0;
9016 VkPipelineLayout pipe_layout_bad_set0;
9017 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0);
9018 ASSERT_VK_SUCCESS(err);
9020 // Create a buffer to update the descriptor with
9022 VkBufferCreateInfo buffCI = {};
9023 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9025 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
9026 buffCI.queueFamilyIndexCount = 1;
9027 buffCI.pQueueFamilyIndices = &qfi;
9030 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
9031 ASSERT_VK_SUCCESS(err);
9032 // Correctly update descriptor to avoid "NOT_UPDATED" error
9033 static const uint32_t NUM_BUFFS = 5;
9034 VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {};
9035 for (uint32_t i = 0; i < NUM_BUFFS; ++i) {
9036 buffInfo[i].buffer = dyub;
9037 buffInfo[i].offset = 0;
9038 buffInfo[i].range = 1024;
9041 const int32_t tex_width = 32;
9042 const int32_t tex_height = 32;
9043 VkImageCreateInfo image_create_info = {};
9044 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9045 image_create_info.pNext = NULL;
9046 image_create_info.imageType = VK_IMAGE_TYPE_2D;
9047 image_create_info.format = tex_format;
9048 image_create_info.extent.width = tex_width;
9049 image_create_info.extent.height = tex_height;
9050 image_create_info.extent.depth = 1;
9051 image_create_info.mipLevels = 1;
9052 image_create_info.arrayLayers = 1;
9053 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9054 image_create_info.tiling = tiling;
9055 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
9056 image_create_info.flags = 0;
9057 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9058 ASSERT_VK_SUCCESS(err);
9060 VkMemoryRequirements memReqs;
9061 VkDeviceMemory imageMem;
9063 VkMemoryAllocateInfo memAlloc = {};
9064 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9065 memAlloc.pNext = NULL;
9066 memAlloc.allocationSize = 0;
9067 memAlloc.memoryTypeIndex = 0;
9068 vkGetImageMemoryRequirements(m_device->device(), image, &memReqs);
9069 memAlloc.allocationSize = memReqs.size;
9070 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
9072 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem);
9073 ASSERT_VK_SUCCESS(err);
9074 err = vkBindImageMemory(m_device->device(), image, imageMem, 0);
9075 ASSERT_VK_SUCCESS(err);
9077 VkImageViewCreateInfo image_view_create_info = {};
9078 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
9079 image_view_create_info.image = image;
9080 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
9081 image_view_create_info.format = tex_format;
9082 image_view_create_info.subresourceRange.layerCount = 1;
9083 image_view_create_info.subresourceRange.baseMipLevel = 0;
9084 image_view_create_info.subresourceRange.levelCount = 1;
9085 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9088 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
9089 ASSERT_VK_SUCCESS(err);
9090 VkDescriptorImageInfo imageInfo[4] = {};
9091 imageInfo[0].imageView = view;
9092 imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9093 imageInfo[1].imageView = view;
9094 imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9095 imageInfo[2].imageView = view;
9096 imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9097 imageInfo[3].imageView = view;
9098 imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9100 static const uint32_t NUM_SET_UPDATES = 3;
9101 VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
9102 descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9103 descriptor_write[0].dstSet = descriptorSet[0];
9104 descriptor_write[0].dstBinding = 0;
9105 descriptor_write[0].descriptorCount = 5;
9106 descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9107 descriptor_write[0].pBufferInfo = buffInfo;
9108 descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9109 descriptor_write[1].dstSet = descriptorSet[1];
9110 descriptor_write[1].dstBinding = 0;
9111 descriptor_write[1].descriptorCount = 2;
9112 descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9113 descriptor_write[1].pImageInfo = imageInfo;
9114 descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9115 descriptor_write[2].dstSet = descriptorSet[1];
9116 descriptor_write[2].dstBinding = 1;
9117 descriptor_write[2].descriptorCount = 2;
9118 descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9119 descriptor_write[2].pImageInfo = &imageInfo[2];
9121 vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL);
9123 // Create PSO to be used for draw-time errors below
9124 char const *vsSource = "#version 450\n"
9126 "out gl_PerVertex {\n"
9127 " vec4 gl_Position;\n"
9130 " gl_Position = vec4(1);\n"
9132 char const *fsSource = "#version 450\n"
9134 "layout(location=0) out vec4 x;\n"
9135 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
9137 " x = vec4(bar.y);\n"
9139 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9140 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9141 VkPipelineObj pipe(m_device);
9142 pipe.AddShader(&vs);
9143 pipe.AddShader(&fs);
9144 pipe.AddColorAttachment();
9145 pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass());
9147 BeginCommandBuffer();
9149 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9150 // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
9152 // here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
9154 // due to the fact that cmd_alloc_dset_data() has not been called in
9155 // cmd_bind_graphics_pipeline()
9156 // TODO : Want to cause various binding incompatibility issues here to test
9158 // First cause various verify_layout_compatibility() fails
9159 // Second disturb early and late sets and verify INFO msgs
9160 // verify_set_layout_compatibility fail cases:
9161 // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
9162 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object ");
9163 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
9164 (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL);
9165 m_errorMonitor->VerifyFound();
9167 // 2. layoutIndex exceeds # of layouts in layout
9168 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
9169 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2,
9170 &descriptorSet[0], 0, NULL);
9171 m_errorMonitor->VerifyFound();
9173 vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL);
9174 // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
9176 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
9177 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1,
9178 &descriptorSet[0], 0, NULL);
9179 m_errorMonitor->VerifyFound();
9181 vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL);
9182 // 4. same # of descriptors but mismatch in type
9183 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
9184 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1,
9185 &descriptorSet[0], 0, NULL);
9186 m_errorMonitor->VerifyFound();
9188 vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL);
9189 // 5. same # of descriptors but mismatch in stageFlags
9190 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9191 " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
9192 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9193 &descriptorSet[0], 0, NULL);
9194 m_errorMonitor->VerifyFound();
9196 // Cause INFO messages due to disturbing previously bound Sets
9197 // First bind sets 0 & 1
9198 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9199 &descriptorSet[0], 0, NULL);
9200 // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout
9201 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed ");
9202 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9203 &descriptorSet[1], 0, NULL);
9204 m_errorMonitor->VerifyFound();
9206 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9207 &descriptorSet[0], 0, NULL);
9208 // 2. Disturb set after last bound set
9209 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and "
9210 "any subsequent sets were disturbed ");
9211 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1,
9212 &ds0_fs_only, 0, NULL);
9213 m_errorMonitor->VerifyFound();
9215 // Now that we're done actively using the pipelineLayout that gfx pipeline
9216 // was created with, we should be able to delete it. Do that now to verify
9217 // that validation obeys pipelineLayout lifetime
9218 vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
9220 // Cause draw-time errors due to PSO incompatibilities
9221 // 1. Error due to not binding required set (we actually use same code as
9222 // above to disturb set0)
9223 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9224 &descriptorSet[0], 0, NULL);
9225 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1,
9226 &descriptorSet[1], 0, NULL);
9227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
9229 m_errorMonitor->VerifyFound();
9231 vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL);
9232 // 2. Error due to bound set not being compatible with PSO's
9233 // VkPipelineLayout (diff stageFlags in this case)
9234 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2,
9235 &descriptorSet[0], 0, NULL);
9236 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
9238 m_errorMonitor->VerifyFound();
9240 // Remaining clean-up
9241 for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
9242 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
9244 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
9245 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
9246 vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
9247 vkDestroyBuffer(m_device->device(), dyub, NULL);
9248 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9249 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9250 vkFreeMemory(m_device->device(), imageMem, NULL);
9251 vkDestroyImage(m_device->device(), image, NULL);
9252 vkDestroyImageView(m_device->device(), view, NULL);
9255 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
9257 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9258 "You must call vkBeginCommandBuffer() before this call to ");
9260 ASSERT_NO_FATAL_FAILURE(InitState());
9261 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9262 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
9263 vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9265 m_errorMonitor->VerifyFound();
9268 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
9270 VkCommandBuffer draw_cmd;
9272 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter.");
9274 ASSERT_NO_FATAL_FAILURE(InitState());
9276 VkCommandBufferAllocateInfo cmd = {};
9277 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
9279 cmd.commandPool = m_commandPool;
9280 cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
9281 cmd.commandBufferCount = 1;
9283 err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd);
9284 ASSERT_VK_SUCCESS(err);
9286 // Force the failure by not setting the Renderpass and Framebuffer fields
9287 VkCommandBufferBeginInfo cmd_buf_info = {};
9288 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9289 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9290 cmd_buf_info.pNext = NULL;
9291 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
9292 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9294 // The error should be caught by validation of the BeginCommandBuffer call
9295 vkBeginCommandBuffer(draw_cmd, &cmd_buf_info);
9297 m_errorMonitor->VerifyFound();
9298 vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd);
9301 TEST_F(VkLayerTest, CommandBufferResetErrors) {
9302 // Cause error due to Begin while recording CB
9303 // Then cause 2 errors for attempting to reset CB w/o having
9304 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
9305 // which CBs were allocated. Note that this bit is off by default.
9306 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
9308 ASSERT_NO_FATAL_FAILURE(InitState());
9310 // Calls AllocateCommandBuffers
9311 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
9313 // Force the failure by setting the Renderpass and Framebuffer fields with
9315 VkCommandBufferBeginInfo cmd_buf_info = {};
9316 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
9317 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
9318 cmd_buf_info.pNext = NULL;
9319 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
9320 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
9322 // Begin CB to transition to recording state
9323 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9324 // Can't re-begin. This should trigger error
9325 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9326 m_errorMonitor->VerifyFound();
9328 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer ");
9329 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
9330 // Reset attempt will trigger error due to incorrect CommandPool state
9331 vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags);
9332 m_errorMonitor->VerifyFound();
9334 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from ");
9335 // Transition CB to RECORDED state
9336 vkEndCommandBuffer(commandBuffer.GetBufferHandle());
9337 // Now attempting to Begin will implicitly reset, which triggers error
9338 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info);
9339 m_errorMonitor->VerifyFound();
9342 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
9343 // Attempt to Create Gfx Pipeline w/o a VS
9346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
9348 ASSERT_NO_FATAL_FAILURE(InitState());
9349 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9351 VkDescriptorPoolSize ds_type_count = {};
9352 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9353 ds_type_count.descriptorCount = 1;
9355 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9356 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9357 ds_pool_ci.pNext = NULL;
9358 ds_pool_ci.maxSets = 1;
9359 ds_pool_ci.poolSizeCount = 1;
9360 ds_pool_ci.pPoolSizes = &ds_type_count;
9362 VkDescriptorPool ds_pool;
9363 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9364 ASSERT_VK_SUCCESS(err);
9366 VkDescriptorSetLayoutBinding dsl_binding = {};
9367 dsl_binding.binding = 0;
9368 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9369 dsl_binding.descriptorCount = 1;
9370 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9371 dsl_binding.pImmutableSamplers = NULL;
9373 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9374 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9375 ds_layout_ci.pNext = NULL;
9376 ds_layout_ci.bindingCount = 1;
9377 ds_layout_ci.pBindings = &dsl_binding;
9379 VkDescriptorSetLayout ds_layout;
9380 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9381 ASSERT_VK_SUCCESS(err);
9383 VkDescriptorSet descriptorSet;
9384 VkDescriptorSetAllocateInfo alloc_info = {};
9385 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9386 alloc_info.descriptorSetCount = 1;
9387 alloc_info.descriptorPool = ds_pool;
9388 alloc_info.pSetLayouts = &ds_layout;
9389 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9390 ASSERT_VK_SUCCESS(err);
9392 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9393 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9394 pipeline_layout_ci.setLayoutCount = 1;
9395 pipeline_layout_ci.pSetLayouts = &ds_layout;
9397 VkPipelineLayout pipeline_layout;
9398 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9399 ASSERT_VK_SUCCESS(err);
9401 VkViewport vp = {}; // Just need dummy vp to point to
9402 VkRect2D sc = {}; // dummy scissor to point to
9404 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9405 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9406 vp_state_ci.scissorCount = 1;
9407 vp_state_ci.pScissors = ≻
9408 vp_state_ci.viewportCount = 1;
9409 vp_state_ci.pViewports = &vp;
9411 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9412 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9413 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9414 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9415 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9416 rs_state_ci.depthClampEnable = VK_FALSE;
9417 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9418 rs_state_ci.depthBiasEnable = VK_FALSE;
9420 VkGraphicsPipelineCreateInfo gp_ci = {};
9421 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9422 gp_ci.pViewportState = &vp_state_ci;
9423 gp_ci.pRasterizationState = &rs_state_ci;
9424 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9425 gp_ci.layout = pipeline_layout;
9426 gp_ci.renderPass = renderPass();
9428 VkPipelineCacheCreateInfo pc_ci = {};
9429 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9430 pc_ci.initialDataSize = 0;
9431 pc_ci.pInitialData = 0;
9433 VkPipeline pipeline;
9434 VkPipelineCache pipelineCache;
9436 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9437 ASSERT_VK_SUCCESS(err);
9438 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9440 m_errorMonitor->VerifyFound();
9442 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9443 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9444 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9445 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9447 /*// TODO : This test should be good, but needs Tess support in compiler to run
9448 TEST_F(VkLayerTest, InvalidPatchControlPoints)
9450 // Attempt to Create Gfx Pipeline w/o a VS
9453 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9454 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
9457 ASSERT_NO_FATAL_FAILURE(InitState());
9458 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9460 VkDescriptorPoolSize ds_type_count = {};
9461 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9462 ds_type_count.descriptorCount = 1;
9464 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9465 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9466 ds_pool_ci.pNext = NULL;
9467 ds_pool_ci.poolSizeCount = 1;
9468 ds_pool_ci.pPoolSizes = &ds_type_count;
9470 VkDescriptorPool ds_pool;
9471 err = vkCreateDescriptorPool(m_device->device(),
9472 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
9473 ASSERT_VK_SUCCESS(err);
9475 VkDescriptorSetLayoutBinding dsl_binding = {};
9476 dsl_binding.binding = 0;
9477 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9478 dsl_binding.descriptorCount = 1;
9479 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9480 dsl_binding.pImmutableSamplers = NULL;
9482 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9483 ds_layout_ci.sType =
9484 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9485 ds_layout_ci.pNext = NULL;
9486 ds_layout_ci.bindingCount = 1;
9487 ds_layout_ci.pBindings = &dsl_binding;
9489 VkDescriptorSetLayout ds_layout;
9490 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
9492 ASSERT_VK_SUCCESS(err);
9494 VkDescriptorSet descriptorSet;
9495 err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
9496 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
9497 ASSERT_VK_SUCCESS(err);
9499 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9500 pipeline_layout_ci.sType =
9501 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9502 pipeline_layout_ci.pNext = NULL;
9503 pipeline_layout_ci.setLayoutCount = 1;
9504 pipeline_layout_ci.pSetLayouts = &ds_layout;
9506 VkPipelineLayout pipeline_layout;
9507 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
9509 ASSERT_VK_SUCCESS(err);
9511 VkPipelineShaderStageCreateInfo shaderStages[3];
9512 memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
9514 VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
9516 // Just using VS txt for Tess shaders as we don't care about functionality
9518 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9521 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9524 shaderStages[0].sType =
9525 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9526 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
9527 shaderStages[0].shader = vs.handle();
9528 shaderStages[1].sType =
9529 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9530 shaderStages[1].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
9531 shaderStages[1].shader = tc.handle();
9532 shaderStages[2].sType =
9533 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
9534 shaderStages[2].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
9535 shaderStages[2].shader = te.handle();
9537 VkPipelineInputAssemblyStateCreateInfo iaCI = {};
9539 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9540 iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
9542 VkPipelineTessellationStateCreateInfo tsCI = {};
9543 tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
9544 tsCI.patchControlPoints = 0; // This will cause an error
9546 VkGraphicsPipelineCreateInfo gp_ci = {};
9547 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9549 gp_ci.stageCount = 3;
9550 gp_ci.pStages = shaderStages;
9551 gp_ci.pVertexInputState = NULL;
9552 gp_ci.pInputAssemblyState = &iaCI;
9553 gp_ci.pTessellationState = &tsCI;
9554 gp_ci.pViewportState = NULL;
9555 gp_ci.pRasterizationState = NULL;
9556 gp_ci.pMultisampleState = NULL;
9557 gp_ci.pDepthStencilState = NULL;
9558 gp_ci.pColorBlendState = NULL;
9559 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9560 gp_ci.layout = pipeline_layout;
9561 gp_ci.renderPass = renderPass();
9563 VkPipelineCacheCreateInfo pc_ci = {};
9564 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9566 pc_ci.initialSize = 0;
9567 pc_ci.initialData = 0;
9570 VkPipeline pipeline;
9571 VkPipelineCache pipelineCache;
9573 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
9575 ASSERT_VK_SUCCESS(err);
9576 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
9577 &gp_ci, NULL, &pipeline);
9579 m_errorMonitor->VerifyFound();
9581 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9582 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9583 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9584 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9587 // Set scissor and viewport counts to different numbers
9588 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) {
9591 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9592 "Gfx Pipeline viewport count (1) must match scissor count (0).");
9594 ASSERT_NO_FATAL_FAILURE(InitState());
9595 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9597 VkDescriptorPoolSize ds_type_count = {};
9598 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9599 ds_type_count.descriptorCount = 1;
9601 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9602 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9603 ds_pool_ci.maxSets = 1;
9604 ds_pool_ci.poolSizeCount = 1;
9605 ds_pool_ci.pPoolSizes = &ds_type_count;
9607 VkDescriptorPool ds_pool;
9608 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9609 ASSERT_VK_SUCCESS(err);
9611 VkDescriptorSetLayoutBinding dsl_binding = {};
9612 dsl_binding.binding = 0;
9613 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9614 dsl_binding.descriptorCount = 1;
9615 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9617 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9618 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9619 ds_layout_ci.bindingCount = 1;
9620 ds_layout_ci.pBindings = &dsl_binding;
9622 VkDescriptorSetLayout ds_layout;
9623 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9624 ASSERT_VK_SUCCESS(err);
9626 VkDescriptorSet descriptorSet;
9627 VkDescriptorSetAllocateInfo alloc_info = {};
9628 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9629 alloc_info.descriptorSetCount = 1;
9630 alloc_info.descriptorPool = ds_pool;
9631 alloc_info.pSetLayouts = &ds_layout;
9632 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9633 ASSERT_VK_SUCCESS(err);
9635 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9636 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9637 pipeline_layout_ci.setLayoutCount = 1;
9638 pipeline_layout_ci.pSetLayouts = &ds_layout;
9640 VkPipelineLayout pipeline_layout;
9641 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9642 ASSERT_VK_SUCCESS(err);
9644 VkViewport vp = {}; // Just need dummy vp to point to
9646 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9647 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9648 vp_state_ci.scissorCount = 0;
9649 vp_state_ci.viewportCount = 1; // Count mismatch should cause error
9650 vp_state_ci.pViewports = &vp;
9652 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9653 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9654 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9655 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9656 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9657 rs_state_ci.depthClampEnable = VK_FALSE;
9658 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9659 rs_state_ci.depthBiasEnable = VK_FALSE;
9661 VkPipelineShaderStageCreateInfo shaderStages[2];
9662 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9664 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9665 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9666 // but add it to be able to run on more devices
9667 shaderStages[0] = vs.GetStageCreateInfo();
9668 shaderStages[1] = fs.GetStageCreateInfo();
9670 VkGraphicsPipelineCreateInfo gp_ci = {};
9671 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9672 gp_ci.stageCount = 2;
9673 gp_ci.pStages = shaderStages;
9674 gp_ci.pViewportState = &vp_state_ci;
9675 gp_ci.pRasterizationState = &rs_state_ci;
9676 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9677 gp_ci.layout = pipeline_layout;
9678 gp_ci.renderPass = renderPass();
9680 VkPipelineCacheCreateInfo pc_ci = {};
9681 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9683 VkPipeline pipeline;
9684 VkPipelineCache pipelineCache;
9686 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9687 ASSERT_VK_SUCCESS(err);
9688 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9690 m_errorMonitor->VerifyFound();
9692 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9693 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9694 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9695 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9697 // Don't set viewport state in PSO. This is an error b/c we always need this
9699 // for the counts even if the data is going to be set dynamically.
9700 TEST_F(VkLayerTest, PSOViewportStateNotSet) {
9701 // Attempt to Create Gfx Pipeline w/o a VS
9704 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if ");
9706 ASSERT_NO_FATAL_FAILURE(InitState());
9707 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9709 VkDescriptorPoolSize ds_type_count = {};
9710 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9711 ds_type_count.descriptorCount = 1;
9713 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9714 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9715 ds_pool_ci.maxSets = 1;
9716 ds_pool_ci.poolSizeCount = 1;
9717 ds_pool_ci.pPoolSizes = &ds_type_count;
9719 VkDescriptorPool ds_pool;
9720 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9721 ASSERT_VK_SUCCESS(err);
9723 VkDescriptorSetLayoutBinding dsl_binding = {};
9724 dsl_binding.binding = 0;
9725 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9726 dsl_binding.descriptorCount = 1;
9727 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9729 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9730 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9731 ds_layout_ci.bindingCount = 1;
9732 ds_layout_ci.pBindings = &dsl_binding;
9734 VkDescriptorSetLayout ds_layout;
9735 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9736 ASSERT_VK_SUCCESS(err);
9738 VkDescriptorSet descriptorSet;
9739 VkDescriptorSetAllocateInfo alloc_info = {};
9740 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9741 alloc_info.descriptorSetCount = 1;
9742 alloc_info.descriptorPool = ds_pool;
9743 alloc_info.pSetLayouts = &ds_layout;
9744 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9745 ASSERT_VK_SUCCESS(err);
9747 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9748 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9749 pipeline_layout_ci.setLayoutCount = 1;
9750 pipeline_layout_ci.pSetLayouts = &ds_layout;
9752 VkPipelineLayout pipeline_layout;
9753 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9754 ASSERT_VK_SUCCESS(err);
9756 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9757 // Set scissor as dynamic to avoid second error
9758 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9759 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9760 dyn_state_ci.dynamicStateCount = 1;
9761 dyn_state_ci.pDynamicStates = &sc_state;
9763 VkPipelineShaderStageCreateInfo shaderStages[2];
9764 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9766 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9767 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9768 // but add it to be able to run on more devices
9769 shaderStages[0] = vs.GetStageCreateInfo();
9770 shaderStages[1] = fs.GetStageCreateInfo();
9772 VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
9773 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9774 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
9775 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
9776 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
9777 rs_state_ci.depthClampEnable = VK_FALSE;
9778 rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
9779 rs_state_ci.depthBiasEnable = VK_FALSE;
9781 VkGraphicsPipelineCreateInfo gp_ci = {};
9782 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9783 gp_ci.stageCount = 2;
9784 gp_ci.pStages = shaderStages;
9785 gp_ci.pRasterizationState = &rs_state_ci;
9786 gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state
9787 // should cause validation error
9788 gp_ci.pDynamicState = &dyn_state_ci;
9789 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9790 gp_ci.layout = pipeline_layout;
9791 gp_ci.renderPass = renderPass();
9793 VkPipelineCacheCreateInfo pc_ci = {};
9794 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9796 VkPipeline pipeline;
9797 VkPipelineCache pipelineCache;
9799 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9800 ASSERT_VK_SUCCESS(err);
9801 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9803 m_errorMonitor->VerifyFound();
9805 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9806 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9807 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9808 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9810 // Create PSO w/o non-zero viewportCount but no viewport data
9811 // Then run second test where dynamic scissor count doesn't match PSO scissor
9813 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) {
9816 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9817 "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
9819 ASSERT_NO_FATAL_FAILURE(InitState());
9821 if (!m_device->phy().features().multiViewport) {
9822 printf("Device does not support multiple viewports/scissors; skipped.\n");
9826 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9828 VkDescriptorPoolSize ds_type_count = {};
9829 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9830 ds_type_count.descriptorCount = 1;
9832 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9833 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9834 ds_pool_ci.maxSets = 1;
9835 ds_pool_ci.poolSizeCount = 1;
9836 ds_pool_ci.pPoolSizes = &ds_type_count;
9838 VkDescriptorPool ds_pool;
9839 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9840 ASSERT_VK_SUCCESS(err);
9842 VkDescriptorSetLayoutBinding dsl_binding = {};
9843 dsl_binding.binding = 0;
9844 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9845 dsl_binding.descriptorCount = 1;
9846 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
9848 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9849 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9850 ds_layout_ci.bindingCount = 1;
9851 ds_layout_ci.pBindings = &dsl_binding;
9853 VkDescriptorSetLayout ds_layout;
9854 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9855 ASSERT_VK_SUCCESS(err);
9857 VkDescriptorSet descriptorSet;
9858 VkDescriptorSetAllocateInfo alloc_info = {};
9859 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9860 alloc_info.descriptorSetCount = 1;
9861 alloc_info.descriptorPool = ds_pool;
9862 alloc_info.pSetLayouts = &ds_layout;
9863 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
9864 ASSERT_VK_SUCCESS(err);
9866 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9867 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9868 pipeline_layout_ci.setLayoutCount = 1;
9869 pipeline_layout_ci.pSetLayouts = &ds_layout;
9871 VkPipelineLayout pipeline_layout;
9872 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9873 ASSERT_VK_SUCCESS(err);
9875 VkPipelineViewportStateCreateInfo vp_state_ci = {};
9876 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
9877 vp_state_ci.viewportCount = 1;
9878 vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error
9879 vp_state_ci.scissorCount = 1;
9880 vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error
9882 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR;
9883 // Set scissor as dynamic to avoid that error
9884 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
9885 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
9886 dyn_state_ci.dynamicStateCount = 1;
9887 dyn_state_ci.pDynamicStates = &sc_state;
9889 VkPipelineShaderStageCreateInfo shaderStages[2];
9890 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
9892 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
9893 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
9894 // but add it to be able to run on more devices
9895 shaderStages[0] = vs.GetStageCreateInfo();
9896 shaderStages[1] = fs.GetStageCreateInfo();
9898 VkPipelineVertexInputStateCreateInfo vi_ci = {};
9899 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
9900 vi_ci.pNext = nullptr;
9901 vi_ci.vertexBindingDescriptionCount = 0;
9902 vi_ci.pVertexBindingDescriptions = nullptr;
9903 vi_ci.vertexAttributeDescriptionCount = 0;
9904 vi_ci.pVertexAttributeDescriptions = nullptr;
9906 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
9907 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
9908 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9910 VkPipelineRasterizationStateCreateInfo rs_ci = {};
9911 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
9912 rs_ci.pNext = nullptr;
9914 VkPipelineColorBlendAttachmentState att = {};
9915 att.blendEnable = VK_FALSE;
9916 att.colorWriteMask = 0xf;
9918 VkPipelineColorBlendStateCreateInfo cb_ci = {};
9919 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
9920 cb_ci.pNext = nullptr;
9921 cb_ci.attachmentCount = 1;
9922 cb_ci.pAttachments = &att;
9924 VkGraphicsPipelineCreateInfo gp_ci = {};
9925 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
9926 gp_ci.stageCount = 2;
9927 gp_ci.pStages = shaderStages;
9928 gp_ci.pVertexInputState = &vi_ci;
9929 gp_ci.pInputAssemblyState = &ia_ci;
9930 gp_ci.pViewportState = &vp_state_ci;
9931 gp_ci.pRasterizationState = &rs_ci;
9932 gp_ci.pColorBlendState = &cb_ci;
9933 gp_ci.pDynamicState = &dyn_state_ci;
9934 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
9935 gp_ci.layout = pipeline_layout;
9936 gp_ci.renderPass = renderPass();
9938 VkPipelineCacheCreateInfo pc_ci = {};
9939 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
9941 VkPipeline pipeline;
9942 VkPipelineCache pipelineCache;
9944 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
9945 ASSERT_VK_SUCCESS(err);
9946 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9948 m_errorMonitor->VerifyFound();
9950 // Now hit second fail case where we set scissor w/ different count than PSO
9951 // First need to successfully create the PSO from above by setting
9953 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
9955 VkViewport vp = {}; // Just need dummy vp to point to
9956 vp_state_ci.pViewports = &vp;
9957 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
9958 ASSERT_VK_SUCCESS(err);
9959 BeginCommandBuffer();
9960 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
9961 VkRect2D scissors[1] = {}; // don't care about data
9962 // Count of 2 doesn't match PSO count of 1
9963 vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
9966 m_errorMonitor->VerifyFound();
9968 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
9969 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
9970 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9971 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9972 vkDestroyPipeline(m_device->device(), pipeline, NULL);
9974 // Create PSO w/o non-zero scissorCount but no scissor data
9975 // Then run second test where dynamic viewportCount doesn't match PSO
9977 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) {
9980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
9982 ASSERT_NO_FATAL_FAILURE(InitState());
9984 if (!m_device->phy().features().multiViewport) {
9985 printf("Device does not support multiple viewports/scissors; skipped.\n");
9989 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9991 VkDescriptorPoolSize ds_type_count = {};
9992 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9993 ds_type_count.descriptorCount = 1;
9995 VkDescriptorPoolCreateInfo ds_pool_ci = {};
9996 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9997 ds_pool_ci.maxSets = 1;
9998 ds_pool_ci.poolSizeCount = 1;
9999 ds_pool_ci.pPoolSizes = &ds_type_count;
10001 VkDescriptorPool ds_pool;
10002 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10003 ASSERT_VK_SUCCESS(err);
10005 VkDescriptorSetLayoutBinding dsl_binding = {};
10006 dsl_binding.binding = 0;
10007 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10008 dsl_binding.descriptorCount = 1;
10009 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10011 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10012 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10013 ds_layout_ci.bindingCount = 1;
10014 ds_layout_ci.pBindings = &dsl_binding;
10016 VkDescriptorSetLayout ds_layout;
10017 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10018 ASSERT_VK_SUCCESS(err);
10020 VkDescriptorSet descriptorSet;
10021 VkDescriptorSetAllocateInfo alloc_info = {};
10022 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10023 alloc_info.descriptorSetCount = 1;
10024 alloc_info.descriptorPool = ds_pool;
10025 alloc_info.pSetLayouts = &ds_layout;
10026 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10027 ASSERT_VK_SUCCESS(err);
10029 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10030 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10031 pipeline_layout_ci.setLayoutCount = 1;
10032 pipeline_layout_ci.pSetLayouts = &ds_layout;
10034 VkPipelineLayout pipeline_layout;
10035 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10036 ASSERT_VK_SUCCESS(err);
10038 VkPipelineViewportStateCreateInfo vp_state_ci = {};
10039 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10040 vp_state_ci.scissorCount = 1;
10041 vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error
10042 vp_state_ci.viewportCount = 1;
10043 vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error
10045 VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT;
10046 // Set scissor as dynamic to avoid that error
10047 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10048 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10049 dyn_state_ci.dynamicStateCount = 1;
10050 dyn_state_ci.pDynamicStates = &vp_state;
10052 VkPipelineShaderStageCreateInfo shaderStages[2];
10053 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10055 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10056 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
10057 // but add it to be able to run on more devices
10058 shaderStages[0] = vs.GetStageCreateInfo();
10059 shaderStages[1] = fs.GetStageCreateInfo();
10061 VkPipelineVertexInputStateCreateInfo vi_ci = {};
10062 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10063 vi_ci.pNext = nullptr;
10064 vi_ci.vertexBindingDescriptionCount = 0;
10065 vi_ci.pVertexBindingDescriptions = nullptr;
10066 vi_ci.vertexAttributeDescriptionCount = 0;
10067 vi_ci.pVertexAttributeDescriptions = nullptr;
10069 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10070 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10071 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10073 VkPipelineRasterizationStateCreateInfo rs_ci = {};
10074 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10075 rs_ci.pNext = nullptr;
10077 VkPipelineColorBlendAttachmentState att = {};
10078 att.blendEnable = VK_FALSE;
10079 att.colorWriteMask = 0xf;
10081 VkPipelineColorBlendStateCreateInfo cb_ci = {};
10082 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10083 cb_ci.pNext = nullptr;
10084 cb_ci.attachmentCount = 1;
10085 cb_ci.pAttachments = &att;
10087 VkGraphicsPipelineCreateInfo gp_ci = {};
10088 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10089 gp_ci.stageCount = 2;
10090 gp_ci.pStages = shaderStages;
10091 gp_ci.pVertexInputState = &vi_ci;
10092 gp_ci.pInputAssemblyState = &ia_ci;
10093 gp_ci.pViewportState = &vp_state_ci;
10094 gp_ci.pRasterizationState = &rs_ci;
10095 gp_ci.pColorBlendState = &cb_ci;
10096 gp_ci.pDynamicState = &dyn_state_ci;
10097 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10098 gp_ci.layout = pipeline_layout;
10099 gp_ci.renderPass = renderPass();
10101 VkPipelineCacheCreateInfo pc_ci = {};
10102 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10104 VkPipeline pipeline;
10105 VkPipelineCache pipelineCache;
10107 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10108 ASSERT_VK_SUCCESS(err);
10109 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10111 m_errorMonitor->VerifyFound();
10113 // Now hit second fail case where we set scissor w/ different count than PSO
10114 // First need to successfully create the PSO from above by setting
10116 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
10118 VkRect2D sc = {}; // Just need dummy vp to point to
10119 vp_state_ci.pScissors = ≻
10120 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10121 ASSERT_VK_SUCCESS(err);
10122 BeginCommandBuffer();
10123 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10124 VkViewport viewports[1] = {}; // don't care about data
10125 // Count of 2 doesn't match PSO count of 1
10126 vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
10129 m_errorMonitor->VerifyFound();
10131 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10132 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10133 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10134 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10135 vkDestroyPipeline(m_device->device(), pipeline, NULL);
10138 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
10141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10143 ASSERT_NO_FATAL_FAILURE(InitState());
10144 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10146 VkDescriptorPoolSize ds_type_count = {};
10147 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10148 ds_type_count.descriptorCount = 1;
10150 VkDescriptorPoolCreateInfo ds_pool_ci = {};
10151 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10152 ds_pool_ci.maxSets = 1;
10153 ds_pool_ci.poolSizeCount = 1;
10154 ds_pool_ci.pPoolSizes = &ds_type_count;
10156 VkDescriptorPool ds_pool;
10157 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10158 ASSERT_VK_SUCCESS(err);
10160 VkDescriptorSetLayoutBinding dsl_binding = {};
10161 dsl_binding.binding = 0;
10162 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10163 dsl_binding.descriptorCount = 1;
10164 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10166 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10167 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10168 ds_layout_ci.bindingCount = 1;
10169 ds_layout_ci.pBindings = &dsl_binding;
10171 VkDescriptorSetLayout ds_layout;
10172 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
10173 ASSERT_VK_SUCCESS(err);
10175 VkDescriptorSet descriptorSet;
10176 VkDescriptorSetAllocateInfo alloc_info = {};
10177 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10178 alloc_info.descriptorSetCount = 1;
10179 alloc_info.descriptorPool = ds_pool;
10180 alloc_info.pSetLayouts = &ds_layout;
10181 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10182 ASSERT_VK_SUCCESS(err);
10184 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
10185 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
10186 pipeline_layout_ci.setLayoutCount = 1;
10187 pipeline_layout_ci.pSetLayouts = &ds_layout;
10189 VkPipelineLayout pipeline_layout;
10190 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
10191 ASSERT_VK_SUCCESS(err);
10193 VkPipelineViewportStateCreateInfo vp_state_ci = {};
10194 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
10195 vp_state_ci.scissorCount = 1;
10196 vp_state_ci.pScissors = NULL;
10197 vp_state_ci.viewportCount = 1;
10198 vp_state_ci.pViewports = NULL;
10200 VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
10201 // Set scissor as dynamic to avoid that error
10202 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10203 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10204 dyn_state_ci.dynamicStateCount = 2;
10205 dyn_state_ci.pDynamicStates = dynamic_states;
10207 VkPipelineShaderStageCreateInfo shaderStages[2];
10208 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
10210 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10211 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
10212 this); // TODO - We shouldn't need a fragment shader
10213 // but add it to be able to run on more devices
10214 shaderStages[0] = vs.GetStageCreateInfo();
10215 shaderStages[1] = fs.GetStageCreateInfo();
10217 VkPipelineVertexInputStateCreateInfo vi_ci = {};
10218 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
10219 vi_ci.pNext = nullptr;
10220 vi_ci.vertexBindingDescriptionCount = 0;
10221 vi_ci.pVertexBindingDescriptions = nullptr;
10222 vi_ci.vertexAttributeDescriptionCount = 0;
10223 vi_ci.pVertexAttributeDescriptions = nullptr;
10225 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
10226 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
10227 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
10229 VkPipelineRasterizationStateCreateInfo rs_ci = {};
10230 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
10231 rs_ci.pNext = nullptr;
10233 // Check too low (line width of -1.0f).
10234 rs_ci.lineWidth = -1.0f;
10236 VkPipelineColorBlendAttachmentState att = {};
10237 att.blendEnable = VK_FALSE;
10238 att.colorWriteMask = 0xf;
10240 VkPipelineColorBlendStateCreateInfo cb_ci = {};
10241 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
10242 cb_ci.pNext = nullptr;
10243 cb_ci.attachmentCount = 1;
10244 cb_ci.pAttachments = &att;
10246 VkGraphicsPipelineCreateInfo gp_ci = {};
10247 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
10248 gp_ci.stageCount = 2;
10249 gp_ci.pStages = shaderStages;
10250 gp_ci.pVertexInputState = &vi_ci;
10251 gp_ci.pInputAssemblyState = &ia_ci;
10252 gp_ci.pViewportState = &vp_state_ci;
10253 gp_ci.pRasterizationState = &rs_ci;
10254 gp_ci.pColorBlendState = &cb_ci;
10255 gp_ci.pDynamicState = &dyn_state_ci;
10256 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
10257 gp_ci.layout = pipeline_layout;
10258 gp_ci.renderPass = renderPass();
10260 VkPipelineCacheCreateInfo pc_ci = {};
10261 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
10263 VkPipeline pipeline;
10264 VkPipelineCache pipelineCache;
10266 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10267 ASSERT_VK_SUCCESS(err);
10268 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10270 m_errorMonitor->VerifyFound();
10271 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10273 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10275 // Check too high (line width of 65536.0f).
10276 rs_ci.lineWidth = 65536.0f;
10278 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10279 ASSERT_VK_SUCCESS(err);
10280 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10282 m_errorMonitor->VerifyFound();
10283 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10285 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1");
10287 dyn_state_ci.dynamicStateCount = 3;
10289 rs_ci.lineWidth = 1.0f;
10291 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
10292 ASSERT_VK_SUCCESS(err);
10293 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
10294 BeginCommandBuffer();
10295 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
10297 // Check too low with dynamic setting.
10298 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f);
10299 m_errorMonitor->VerifyFound();
10301 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536");
10303 // Check too high with dynamic setting.
10304 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f);
10305 m_errorMonitor->VerifyFound();
10306 EndCommandBuffer();
10308 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
10309 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
10310 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
10311 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10312 vkDestroyPipeline(m_device->device(), pipeline, NULL);
10315 TEST_F(VkLayerTest, NullRenderPass) {
10316 // Bind a NULL RenderPass
10317 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10318 "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
10320 ASSERT_NO_FATAL_FAILURE(InitState());
10321 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10323 BeginCommandBuffer();
10324 // Don't care about RenderPass handle b/c error should be flagged before
10326 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
10328 m_errorMonitor->VerifyFound();
10331 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
10332 // Bind a BeginRenderPass within an active RenderPass
10333 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10334 "It is invalid to issue this call inside an active render pass");
10336 ASSERT_NO_FATAL_FAILURE(InitState());
10337 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10339 BeginCommandBuffer();
10340 // Just create a dummy Renderpass that's non-NULL so we can get to the
10342 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10344 m_errorMonitor->VerifyFound();
10347 TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
10348 m_errorMonitor->ExpectSuccess();
10350 ASSERT_NO_FATAL_FAILURE(InitState());
10351 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10353 BeginCommandBuffer(); // framework implicitly begins the renderpass.
10354 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
10356 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
10357 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10358 m_errorMonitor->VerifyNotFound();
10359 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10360 m_errorMonitor->VerifyNotFound();
10361 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10362 m_errorMonitor->VerifyNotFound();
10364 m_commandBuffer->EndCommandBuffer();
10365 m_errorMonitor->VerifyNotFound();
10368 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
10369 TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
10370 "the number of renderPass attachments that use loadOp"
10371 "VK_ATTACHMENT_LOAD_OP_CLEAR.");
10373 ASSERT_NO_FATAL_FAILURE(InitState());
10374 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10376 // Create a renderPass with a single attachment that uses loadOp CLEAR
10377 VkAttachmentReference attach = {};
10378 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
10379 VkSubpassDescription subpass = {};
10380 subpass.inputAttachmentCount = 1;
10381 subpass.pInputAttachments = &attach;
10382 VkRenderPassCreateInfo rpci = {};
10383 rpci.subpassCount = 1;
10384 rpci.pSubpasses = &subpass;
10385 rpci.attachmentCount = 1;
10386 VkAttachmentDescription attach_desc = {};
10387 attach_desc.format = VK_FORMAT_UNDEFINED;
10388 // Set loadOp to CLEAR
10389 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10390 rpci.pAttachments = &attach_desc;
10391 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10393 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
10395 VkCommandBufferInheritanceInfo hinfo = {};
10396 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10397 hinfo.renderPass = VK_NULL_HANDLE;
10399 hinfo.framebuffer = VK_NULL_HANDLE;
10400 hinfo.occlusionQueryEnable = VK_FALSE;
10401 hinfo.queryFlags = 0;
10402 hinfo.pipelineStatistics = 0;
10403 VkCommandBufferBeginInfo info = {};
10404 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
10405 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10406 info.pInheritanceInfo = &hinfo;
10408 vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
10409 VkRenderPassBeginInfo rp_begin = {};
10410 rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
10411 rp_begin.pNext = NULL;
10412 rp_begin.renderPass = renderPass();
10413 rp_begin.framebuffer = framebuffer();
10414 rp_begin.clearValueCount = 0; // Should be 1
10416 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but "
10417 "there must be at least 1 entries in "
10418 "pClearValues array to account for ");
10420 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
10422 m_errorMonitor->VerifyFound();
10424 vkDestroyRenderPass(m_device->device(), rp, NULL);
10427 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
10429 TEST_DESCRIPTION("End a command buffer with an active render pass");
10431 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10432 "It is invalid to issue this call inside an active render pass");
10434 ASSERT_NO_FATAL_FAILURE(InitState());
10435 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10437 // The framework's BeginCommandBuffer calls CreateRenderPass
10438 BeginCommandBuffer();
10440 // Call directly into vkEndCommandBuffer instead of the
10441 // the framework's EndCommandBuffer, which inserts a
10443 vkEndCommandBuffer(m_commandBuffer->GetBufferHandle());
10445 m_errorMonitor->VerifyFound();
10447 // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
10448 // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
10451 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
10452 // Call CmdFillBuffer within an active renderpass
10453 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10454 "It is invalid to issue this call inside an active render pass");
10456 ASSERT_NO_FATAL_FAILURE(InitState());
10457 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10459 // Renderpass is started here
10460 BeginCommandBuffer();
10462 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10463 vk_testing::Buffer dstBuffer;
10464 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10466 m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
10468 m_errorMonitor->VerifyFound();
10471 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
10472 // Call CmdUpdateBuffer within an active renderpass
10473 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10474 "It is invalid to issue this call inside an active render pass");
10476 ASSERT_NO_FATAL_FAILURE(InitState());
10477 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10479 // Renderpass is started here
10480 BeginCommandBuffer();
10482 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10483 vk_testing::Buffer dstBuffer;
10484 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
10486 VkDeviceSize dstOffset = 0;
10487 VkDeviceSize dataSize = 1024;
10488 const void *pData = NULL;
10490 vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData);
10492 m_errorMonitor->VerifyFound();
10495 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
10496 // Call CmdClearColorImage within an active RenderPass
10497 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10498 "It is invalid to issue this call inside an active render pass");
10500 ASSERT_NO_FATAL_FAILURE(InitState());
10501 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10503 // Renderpass is started here
10504 BeginCommandBuffer();
10506 VkClearColorValue clear_color;
10507 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
10508 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
10509 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10510 const int32_t tex_width = 32;
10511 const int32_t tex_height = 32;
10512 VkImageCreateInfo image_create_info = {};
10513 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10514 image_create_info.pNext = NULL;
10515 image_create_info.imageType = VK_IMAGE_TYPE_2D;
10516 image_create_info.format = tex_format;
10517 image_create_info.extent.width = tex_width;
10518 image_create_info.extent.height = tex_height;
10519 image_create_info.extent.depth = 1;
10520 image_create_info.mipLevels = 1;
10521 image_create_info.arrayLayers = 1;
10522 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10523 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
10524 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10526 vk_testing::Image dstImage;
10527 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10529 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
10531 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
10533 m_errorMonitor->VerifyFound();
10536 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) {
10537 // Call CmdClearDepthStencilImage within an active RenderPass
10538 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10539 "It is invalid to issue this call inside an active render pass");
10541 ASSERT_NO_FATAL_FAILURE(InitState());
10542 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10544 // Renderpass is started here
10545 BeginCommandBuffer();
10547 VkClearDepthStencilValue clear_value = {0};
10548 VkMemoryPropertyFlags reqs = 0;
10549 VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
10550 image_create_info.imageType = VK_IMAGE_TYPE_2D;
10551 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
10552 image_create_info.extent.width = 64;
10553 image_create_info.extent.height = 64;
10554 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10555 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
10557 vk_testing::Image dstImage;
10558 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
10560 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
10562 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(),
10563 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range);
10565 m_errorMonitor->VerifyFound();
10568 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
10569 // Call CmdClearAttachmentss outside of an active RenderPass
10572 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call "
10573 "must be issued inside an active "
10576 ASSERT_NO_FATAL_FAILURE(InitState());
10577 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10579 // Start no RenderPass
10580 err = m_commandBuffer->BeginCommandBuffer();
10581 ASSERT_VK_SUCCESS(err);
10583 VkClearAttachment color_attachment;
10584 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10585 color_attachment.clearValue.color.float32[0] = 0;
10586 color_attachment.clearValue.color.float32[1] = 0;
10587 color_attachment.clearValue.color.float32[2] = 0;
10588 color_attachment.clearValue.color.float32[3] = 0;
10589 color_attachment.colorAttachment = 0;
10590 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
10591 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
10593 m_errorMonitor->VerifyFound();
10596 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
10597 TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is "
10598 "called too many times in a renderpass instance");
10600 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance "
10601 "beyond final subpass");
10603 ASSERT_NO_FATAL_FAILURE(InitState());
10604 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10606 BeginCommandBuffer();
10609 vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE);
10610 m_errorMonitor->VerifyFound();
10612 EndCommandBuffer();
10615 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
10616 TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is "
10617 "called before the final subpass has been reached");
10619 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching "
10622 ASSERT_NO_FATAL_FAILURE(InitState());
10623 VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
10624 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
10626 VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
10629 VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
10630 ASSERT_VK_SUCCESS(err);
10632 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
10635 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
10636 ASSERT_VK_SUCCESS(err);
10638 m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin
10640 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
10642 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
10645 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10646 m_errorMonitor->VerifyFound();
10649 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
10650 vkDestroyRenderPass(m_device->device(), rp, nullptr);
10653 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
10654 // Try to add a buffer memory barrier with no buffer.
10655 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10656 "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
10658 ASSERT_NO_FATAL_FAILURE(InitState());
10659 BeginCommandBuffer();
10661 VkBufferMemoryBarrier buf_barrier = {};
10662 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10663 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10664 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10665 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10666 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10667 buf_barrier.buffer = VK_NULL_HANDLE;
10668 buf_barrier.offset = 0;
10669 buf_barrier.size = VK_WHOLE_SIZE;
10670 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10671 nullptr, 1, &buf_barrier, 0, nullptr);
10673 m_errorMonitor->VerifyFound();
10676 TEST_F(VkLayerTest, InvalidBarriers) {
10677 TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
10679 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass");
10681 ASSERT_NO_FATAL_FAILURE(InitState());
10682 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10684 VkMemoryBarrier mem_barrier = {};
10685 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
10686 mem_barrier.pNext = NULL;
10687 mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10688 mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10689 BeginCommandBuffer();
10690 // BeginCommandBuffer() starts a render pass
10691 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
10692 &mem_barrier, 0, nullptr, 0, nullptr);
10693 m_errorMonitor->VerifyFound();
10695 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
10696 VkImageObj image(m_device);
10697 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10698 ASSERT_TRUE(image.initialized());
10699 VkImageMemoryBarrier img_barrier = {};
10700 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10701 img_barrier.pNext = NULL;
10702 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10703 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10704 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10705 // New layout can't be UNDEFINED
10706 img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10707 img_barrier.image = image.handle();
10708 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10709 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10710 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10711 img_barrier.subresourceRange.baseArrayLayer = 0;
10712 img_barrier.subresourceRange.baseMipLevel = 0;
10713 img_barrier.subresourceRange.layerCount = 1;
10714 img_barrier.subresourceRange.levelCount = 1;
10715 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10716 nullptr, 0, nullptr, 1, &img_barrier);
10717 m_errorMonitor->VerifyFound();
10718 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10720 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the "
10722 // baseArrayLayer + layerCount must be <= image's arrayLayers
10723 img_barrier.subresourceRange.baseArrayLayer = 1;
10724 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10725 nullptr, 0, nullptr, 1, &img_barrier);
10726 m_errorMonitor->VerifyFound();
10727 img_barrier.subresourceRange.baseArrayLayer = 0;
10729 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel");
10730 // baseMipLevel + levelCount must be <= image's mipLevels
10731 img_barrier.subresourceRange.baseMipLevel = 1;
10732 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10733 nullptr, 0, nullptr, 1, &img_barrier);
10734 m_errorMonitor->VerifyFound();
10735 img_barrier.subresourceRange.baseMipLevel = 0;
10737 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
10738 vk_testing::Buffer buffer;
10739 buffer.init(*m_device, 256);
10740 VkBufferMemoryBarrier buf_barrier = {};
10741 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
10742 buf_barrier.pNext = NULL;
10743 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
10744 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10745 buf_barrier.buffer = buffer.handle();
10746 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10747 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10748 buf_barrier.offset = 0;
10749 buf_barrier.size = VK_WHOLE_SIZE;
10750 // Can't send buffer barrier during a render pass
10751 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10752 nullptr, 1, &buf_barrier, 0, nullptr);
10753 m_errorMonitor->VerifyFound();
10754 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
10756 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
10757 buf_barrier.offset = 257;
10758 // Offset greater than total size
10759 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10760 nullptr, 1, &buf_barrier, 0, nullptr);
10761 m_errorMonitor->VerifyFound();
10762 buf_barrier.offset = 0;
10764 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
10765 buf_barrier.size = 257;
10766 // Size greater than total size
10767 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10768 nullptr, 1, &buf_barrier, 0, nullptr);
10769 m_errorMonitor->VerifyFound();
10771 // Now exercise barrier aspect bit errors, first DS
10772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must "
10773 "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
10774 "VK_IMAGE_ASPECT_STENCIL_BIT set.");
10775 VkDepthStencilObj ds_image(m_device);
10776 ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
10777 ASSERT_TRUE(ds_image.initialized());
10778 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10779 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10780 img_barrier.image = ds_image.handle();
10781 // Use of COLOR aspect on DS image is error
10782 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10783 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10784 nullptr, 0, nullptr, 1, &img_barrier);
10785 m_errorMonitor->VerifyFound();
10786 // Now test depth-only
10787 VkFormatProperties format_props;
10789 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
10790 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must "
10792 "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
10793 VkDepthStencilObj d_image(m_device);
10794 d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
10795 ASSERT_TRUE(d_image.initialized());
10796 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10797 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10798 img_barrier.image = d_image.handle();
10799 // Use of COLOR aspect on depth image is error
10800 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10801 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10802 0, nullptr, 0, nullptr, 1, &img_barrier);
10803 m_errorMonitor->VerifyFound();
10805 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
10806 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
10807 // Now test stencil-only
10808 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must "
10809 "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
10810 VkDepthStencilObj s_image(m_device);
10811 s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
10812 ASSERT_TRUE(s_image.initialized());
10813 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
10814 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10815 img_barrier.image = s_image.handle();
10816 // Use of COLOR aspect on depth image is error
10817 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10818 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
10819 0, nullptr, 0, nullptr, 1, &img_barrier);
10820 m_errorMonitor->VerifyFound();
10822 // Finally test color
10823 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
10824 "have VK_IMAGE_ASPECT_COLOR_BIT set.");
10825 VkImageObj c_image(m_device);
10826 c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10827 ASSERT_TRUE(c_image.initialized());
10828 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10829 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
10830 img_barrier.image = c_image.handle();
10831 // Set aspect to depth (non-color)
10832 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
10833 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
10834 nullptr, 0, nullptr, 1, &img_barrier);
10835 m_errorMonitor->VerifyFound();
10838 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
10839 // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
10841 m_errorMonitor->SetDesiredFailureMsg(
10842 VK_DEBUG_REPORT_WARNING_BIT_EXT,
10843 "must have required access bit");
10844 ASSERT_NO_FATAL_FAILURE(InitState());
10845 VkImageObj image(m_device);
10846 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10847 ASSERT_TRUE(image.initialized());
10849 VkImageMemoryBarrier barrier = {};
10850 VkImageSubresourceRange range;
10851 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10852 barrier.srcAccessMask = 0;
10853 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
10854 barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
10855 barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10856 barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10857 barrier.image = image.handle();
10858 range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10859 range.baseMipLevel = 0;
10860 range.levelCount = 1;
10861 range.baseArrayLayer = 0;
10862 range.layerCount = 1;
10863 barrier.subresourceRange = range;
10864 VkCommandBufferObj cmdbuf(m_device, m_commandPool);
10865 cmdbuf.BeginCommandBuffer();
10866 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10868 barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
10869 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10870 barrier.srcAccessMask = 0;
10871 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
10872 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
10875 m_errorMonitor->VerifyFound();
10878 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
10879 // Bind a BeginRenderPass within an active RenderPass
10882 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
10884 ASSERT_NO_FATAL_FAILURE(InitState());
10885 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10887 VkBufferCreateInfo buffCI = {};
10888 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10889 buffCI.size = 1024;
10890 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10891 buffCI.queueFamilyIndexCount = 1;
10892 buffCI.pQueueFamilyIndices = &qfi;
10895 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10896 ASSERT_VK_SUCCESS(err);
10898 BeginCommandBuffer();
10899 ASSERT_VK_SUCCESS(err);
10900 // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
10901 // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10902 // Should error before calling to driver so don't care about actual data
10903 vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16);
10905 m_errorMonitor->VerifyFound();
10907 vkDestroyBuffer(m_device->device(), ib, NULL);
10910 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
10911 // Create an out-of-range queueFamilyIndex
10912 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10913 "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one "
10914 "of the indices specified when the device was created, via the "
10915 "VkDeviceQueueCreateInfo structure.");
10917 ASSERT_NO_FATAL_FAILURE(InitState());
10918 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10919 VkBufferCreateInfo buffCI = {};
10920 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10921 buffCI.size = 1024;
10922 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
10923 buffCI.queueFamilyIndexCount = 1;
10924 // Introduce failure by specifying invalid queue_family_index
10925 uint32_t qfi = 777;
10926 buffCI.pQueueFamilyIndices = &qfi;
10927 buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
10930 vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
10932 m_errorMonitor->VerifyFound();
10933 vkDestroyBuffer(m_device->device(), ib, NULL);
10936 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
10937 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
10938 " (should only be secondary)");
10940 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
10942 ASSERT_NO_FATAL_FAILURE(InitState());
10943 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10945 BeginCommandBuffer();
10947 VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
10948 vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
10950 m_errorMonitor->VerifyFound();
10953 TEST_F(VkLayerTest, DSUsageBitsErrors) {
10954 TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
10955 "that do not have correct usage bits sets.");
10958 ASSERT_NO_FATAL_FAILURE(InitState());
10959 VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10960 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10961 ds_type_count[i].type = VkDescriptorType(i);
10962 ds_type_count[i].descriptorCount = 1;
10964 VkDescriptorPoolCreateInfo ds_pool_ci = {};
10965 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10966 ds_pool_ci.pNext = NULL;
10967 ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10968 ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10969 ds_pool_ci.pPoolSizes = ds_type_count;
10971 VkDescriptorPool ds_pool;
10972 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10973 ASSERT_VK_SUCCESS(err);
10975 // Create 10 layouts where each has a single descriptor of different type
10976 VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10977 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10978 dsl_binding[i].binding = 0;
10979 dsl_binding[i].descriptorType = VkDescriptorType(i);
10980 dsl_binding[i].descriptorCount = 1;
10981 dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
10982 dsl_binding[i].pImmutableSamplers = NULL;
10985 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
10986 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
10987 ds_layout_ci.pNext = NULL;
10988 ds_layout_ci.bindingCount = 1;
10989 VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
10990 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
10991 ds_layout_ci.pBindings = dsl_binding + i;
10992 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i);
10993 ASSERT_VK_SUCCESS(err);
10995 VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
10996 VkDescriptorSetAllocateInfo alloc_info = {};
10997 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10998 alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
10999 alloc_info.descriptorPool = ds_pool;
11000 alloc_info.pSetLayouts = ds_layouts;
11001 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
11002 ASSERT_VK_SUCCESS(err);
11004 // Create a buffer & bufferView to be used for invalid updates
11005 VkBufferCreateInfo buff_ci = {};
11006 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11007 // This usage is not valid for any descriptor type
11008 buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
11009 buff_ci.size = 256;
11010 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11012 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11013 ASSERT_VK_SUCCESS(err);
11015 VkBufferViewCreateInfo buff_view_ci = {};
11016 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11017 buff_view_ci.buffer = buffer;
11018 buff_view_ci.format = VK_FORMAT_R8_UNORM;
11019 buff_view_ci.range = VK_WHOLE_SIZE;
11020 VkBufferView buff_view;
11021 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11022 ASSERT_VK_SUCCESS(err);
11024 // Create an image to be used for invalid updates
11025 VkImageCreateInfo image_ci = {};
11026 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11027 image_ci.imageType = VK_IMAGE_TYPE_2D;
11028 image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11029 image_ci.extent.width = 64;
11030 image_ci.extent.height = 64;
11031 image_ci.extent.depth = 1;
11032 image_ci.mipLevels = 1;
11033 image_ci.arrayLayers = 1;
11034 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11035 image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11036 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11037 // This usage is not valid for any descriptor type
11038 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11039 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11041 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11042 ASSERT_VK_SUCCESS(err);
11043 // Bind memory to image
11044 VkMemoryRequirements mem_reqs;
11045 VkDeviceMemory image_mem;
11047 VkMemoryAllocateInfo mem_alloc = {};
11048 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11049 mem_alloc.pNext = NULL;
11050 mem_alloc.allocationSize = 0;
11051 mem_alloc.memoryTypeIndex = 0;
11052 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11053 mem_alloc.allocationSize = mem_reqs.size;
11054 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11056 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11057 ASSERT_VK_SUCCESS(err);
11058 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11059 ASSERT_VK_SUCCESS(err);
11060 // Now create view for image
11061 VkImageViewCreateInfo image_view_ci = {};
11062 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11063 image_view_ci.image = image;
11064 image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
11065 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11066 image_view_ci.subresourceRange.layerCount = 1;
11067 image_view_ci.subresourceRange.baseArrayLayer = 0;
11068 image_view_ci.subresourceRange.levelCount = 1;
11069 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11070 VkImageView image_view;
11071 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11072 ASSERT_VK_SUCCESS(err);
11074 VkDescriptorBufferInfo buff_info = {};
11075 buff_info.buffer = buffer;
11076 VkDescriptorImageInfo img_info = {};
11077 img_info.imageView = image_view;
11078 VkWriteDescriptorSet descriptor_write = {};
11079 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11080 descriptor_write.dstBinding = 0;
11081 descriptor_write.descriptorCount = 1;
11082 descriptor_write.pTexelBufferView = &buff_view;
11083 descriptor_write.pBufferInfo = &buff_info;
11084 descriptor_write.pImageInfo = &img_info;
11086 // These error messages align with VkDescriptorType struct
11087 const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor
11088 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11089 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
11090 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
11091 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
11092 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
11093 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11094 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11095 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
11096 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
11097 " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
11098 // Start loop at 1 as SAMPLER desc type has no usage bit error
11099 for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
11100 descriptor_write.descriptorType = VkDescriptorType(i);
11101 descriptor_write.dstSet = descriptor_sets[i];
11102 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]);
11104 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11106 m_errorMonitor->VerifyFound();
11107 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
11109 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
11110 vkDestroyImage(m_device->device(), image, NULL);
11111 vkFreeMemory(m_device->device(), image_mem, NULL);
11112 vkDestroyImageView(m_device->device(), image_view, NULL);
11113 vkDestroyBuffer(m_device->device(), buffer, NULL);
11114 vkDestroyBufferView(m_device->device(), buff_view, NULL);
11115 vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
11116 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11119 TEST_F(VkLayerTest, DSBufferInfoErrors) {
11120 TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect "
11121 "parameters in VkDescriptorBufferInfo struct. This includes:\n"
11122 "1. offset value greater than buffer size\n"
11123 "2. range value of 0\n"
11124 "3. range value greater than buffer (size - offset)");
11127 ASSERT_NO_FATAL_FAILURE(InitState());
11128 VkDescriptorPoolSize ds_type_count = {};
11129 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11130 ds_type_count.descriptorCount = 1;
11132 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11133 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11134 ds_pool_ci.pNext = NULL;
11135 ds_pool_ci.maxSets = 1;
11136 ds_pool_ci.poolSizeCount = 1;
11137 ds_pool_ci.pPoolSizes = &ds_type_count;
11139 VkDescriptorPool ds_pool;
11140 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11141 ASSERT_VK_SUCCESS(err);
11143 // Create layout with single uniform buffer descriptor
11144 VkDescriptorSetLayoutBinding dsl_binding = {};
11145 dsl_binding.binding = 0;
11146 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11147 dsl_binding.descriptorCount = 1;
11148 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11149 dsl_binding.pImmutableSamplers = NULL;
11151 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11152 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11153 ds_layout_ci.pNext = NULL;
11154 ds_layout_ci.bindingCount = 1;
11155 ds_layout_ci.pBindings = &dsl_binding;
11156 VkDescriptorSetLayout ds_layout;
11157 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11158 ASSERT_VK_SUCCESS(err);
11160 VkDescriptorSet descriptor_set = {};
11161 VkDescriptorSetAllocateInfo alloc_info = {};
11162 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11163 alloc_info.descriptorSetCount = 1;
11164 alloc_info.descriptorPool = ds_pool;
11165 alloc_info.pSetLayouts = &ds_layout;
11166 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11167 ASSERT_VK_SUCCESS(err);
11169 // Create a buffer to be used for invalid updates
11170 VkBufferCreateInfo buff_ci = {};
11171 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11172 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
11173 buff_ci.size = 256;
11174 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11176 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11177 ASSERT_VK_SUCCESS(err);
11178 // Have to bind memory to buffer before descriptor update
11179 VkMemoryAllocateInfo mem_alloc = {};
11180 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11181 mem_alloc.pNext = NULL;
11182 mem_alloc.allocationSize = 256;
11183 mem_alloc.memoryTypeIndex = 0;
11185 VkMemoryRequirements mem_reqs;
11186 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
11187 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11189 vkDestroyBuffer(m_device->device(), buffer, NULL);
11193 VkDeviceMemory mem;
11194 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
11195 ASSERT_VK_SUCCESS(err);
11196 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
11197 ASSERT_VK_SUCCESS(err);
11199 VkDescriptorBufferInfo buff_info = {};
11200 buff_info.buffer = buffer;
11201 // First make offset 1 larger than buffer size
11202 buff_info.offset = 257;
11203 buff_info.range = VK_WHOLE_SIZE;
11204 VkWriteDescriptorSet descriptor_write = {};
11205 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11206 descriptor_write.dstBinding = 0;
11207 descriptor_write.descriptorCount = 1;
11208 descriptor_write.pTexelBufferView = nullptr;
11209 descriptor_write.pBufferInfo = &buff_info;
11210 descriptor_write.pImageInfo = nullptr;
11212 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11213 descriptor_write.dstSet = descriptor_set;
11214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer ");
11216 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11218 m_errorMonitor->VerifyFound();
11219 // Now cause error due to range of 0
11220 buff_info.offset = 0;
11221 buff_info.range = 0;
11222 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11223 " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
11225 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11227 m_errorMonitor->VerifyFound();
11228 // Now cause error due to range exceeding buffer size - offset
11229 buff_info.offset = 128;
11230 buff_info.range = 200;
11231 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size ");
11233 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11235 m_errorMonitor->VerifyFound();
11236 vkFreeMemory(m_device->device(), mem, NULL);
11237 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11238 vkDestroyBuffer(m_device->device(), buffer, NULL);
11239 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11240 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11243 TEST_F(VkLayerTest, DSAspectBitsErrors) {
11244 // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
11245 // are set, but could expand this test to hit more cases.
11246 TEST_DESCRIPTION("Attempt to update descriptor sets for images "
11247 "that do not have correct aspect bits sets.");
11250 ASSERT_NO_FATAL_FAILURE(InitState());
11251 VkDescriptorPoolSize ds_type_count = {};
11252 ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11253 ds_type_count.descriptorCount = 1;
11255 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11256 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11257 ds_pool_ci.pNext = NULL;
11258 ds_pool_ci.maxSets = 5;
11259 ds_pool_ci.poolSizeCount = 1;
11260 ds_pool_ci.pPoolSizes = &ds_type_count;
11262 VkDescriptorPool ds_pool;
11263 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11264 ASSERT_VK_SUCCESS(err);
11266 VkDescriptorSetLayoutBinding dsl_binding = {};
11267 dsl_binding.binding = 0;
11268 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11269 dsl_binding.descriptorCount = 1;
11270 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11271 dsl_binding.pImmutableSamplers = NULL;
11273 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11274 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11275 ds_layout_ci.pNext = NULL;
11276 ds_layout_ci.bindingCount = 1;
11277 ds_layout_ci.pBindings = &dsl_binding;
11278 VkDescriptorSetLayout ds_layout;
11279 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11280 ASSERT_VK_SUCCESS(err);
11282 VkDescriptorSet descriptor_set = {};
11283 VkDescriptorSetAllocateInfo alloc_info = {};
11284 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11285 alloc_info.descriptorSetCount = 1;
11286 alloc_info.descriptorPool = ds_pool;
11287 alloc_info.pSetLayouts = &ds_layout;
11288 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11289 ASSERT_VK_SUCCESS(err);
11291 // Create an image to be used for invalid updates
11292 VkImageCreateInfo image_ci = {};
11293 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11294 image_ci.imageType = VK_IMAGE_TYPE_2D;
11295 image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11296 image_ci.extent.width = 64;
11297 image_ci.extent.height = 64;
11298 image_ci.extent.depth = 1;
11299 image_ci.mipLevels = 1;
11300 image_ci.arrayLayers = 1;
11301 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
11302 image_ci.tiling = VK_IMAGE_TILING_LINEAR;
11303 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
11304 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11305 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11307 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
11308 ASSERT_VK_SUCCESS(err);
11309 // Bind memory to image
11310 VkMemoryRequirements mem_reqs;
11311 VkDeviceMemory image_mem;
11313 VkMemoryAllocateInfo mem_alloc = {};
11314 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11315 mem_alloc.pNext = NULL;
11316 mem_alloc.allocationSize = 0;
11317 mem_alloc.memoryTypeIndex = 0;
11318 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
11319 mem_alloc.allocationSize = mem_reqs.size;
11320 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
11322 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
11323 ASSERT_VK_SUCCESS(err);
11324 err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
11325 ASSERT_VK_SUCCESS(err);
11326 // Now create view for image
11327 VkImageViewCreateInfo image_view_ci = {};
11328 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11329 image_view_ci.image = image;
11330 image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
11331 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
11332 image_view_ci.subresourceRange.layerCount = 1;
11333 image_view_ci.subresourceRange.baseArrayLayer = 0;
11334 image_view_ci.subresourceRange.levelCount = 1;
11335 // Setting both depth & stencil aspect bits is illegal for descriptor
11336 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
11338 VkImageView image_view;
11339 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
11340 ASSERT_VK_SUCCESS(err);
11342 VkDescriptorImageInfo img_info = {};
11343 img_info.imageView = image_view;
11344 VkWriteDescriptorSet descriptor_write = {};
11345 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11346 descriptor_write.dstBinding = 0;
11347 descriptor_write.descriptorCount = 1;
11348 descriptor_write.pTexelBufferView = NULL;
11349 descriptor_write.pBufferInfo = NULL;
11350 descriptor_write.pImageInfo = &img_info;
11351 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
11352 descriptor_write.dstSet = descriptor_set;
11353 const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
11354 "or VK_IMAGE_ASPECT_STENCIL_BIT ";
11355 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
11357 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11359 m_errorMonitor->VerifyFound();
11360 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11361 vkDestroyImage(m_device->device(), image, NULL);
11362 vkFreeMemory(m_device->device(), image_mem, NULL);
11363 vkDestroyImageView(m_device->device(), image_view, NULL);
11364 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
11365 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11368 TEST_F(VkLayerTest, DSTypeMismatch) {
11369 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
11372 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11373 " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update "
11374 "type is VK_DESCRIPTOR_TYPE_SAMPLER");
11376 ASSERT_NO_FATAL_FAILURE(InitState());
11377 // VkDescriptorSetObj descriptorSet(m_device);
11378 VkDescriptorPoolSize ds_type_count = {};
11379 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11380 ds_type_count.descriptorCount = 1;
11382 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11383 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11384 ds_pool_ci.pNext = NULL;
11385 ds_pool_ci.maxSets = 1;
11386 ds_pool_ci.poolSizeCount = 1;
11387 ds_pool_ci.pPoolSizes = &ds_type_count;
11389 VkDescriptorPool ds_pool;
11390 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11391 ASSERT_VK_SUCCESS(err);
11392 VkDescriptorSetLayoutBinding dsl_binding = {};
11393 dsl_binding.binding = 0;
11394 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11395 dsl_binding.descriptorCount = 1;
11396 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11397 dsl_binding.pImmutableSamplers = NULL;
11399 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11400 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11401 ds_layout_ci.pNext = NULL;
11402 ds_layout_ci.bindingCount = 1;
11403 ds_layout_ci.pBindings = &dsl_binding;
11405 VkDescriptorSetLayout ds_layout;
11406 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11407 ASSERT_VK_SUCCESS(err);
11409 VkDescriptorSet descriptorSet;
11410 VkDescriptorSetAllocateInfo alloc_info = {};
11411 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11412 alloc_info.descriptorSetCount = 1;
11413 alloc_info.descriptorPool = ds_pool;
11414 alloc_info.pSetLayouts = &ds_layout;
11415 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11416 ASSERT_VK_SUCCESS(err);
11418 VkSamplerCreateInfo sampler_ci = {};
11419 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11420 sampler_ci.pNext = NULL;
11421 sampler_ci.magFilter = VK_FILTER_NEAREST;
11422 sampler_ci.minFilter = VK_FILTER_NEAREST;
11423 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11424 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11425 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11426 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11427 sampler_ci.mipLodBias = 1.0;
11428 sampler_ci.anisotropyEnable = VK_FALSE;
11429 sampler_ci.maxAnisotropy = 1;
11430 sampler_ci.compareEnable = VK_FALSE;
11431 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11432 sampler_ci.minLod = 1.0;
11433 sampler_ci.maxLod = 1.0;
11434 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11435 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11437 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11438 ASSERT_VK_SUCCESS(err);
11440 VkDescriptorImageInfo info = {};
11441 info.sampler = sampler;
11443 VkWriteDescriptorSet descriptor_write;
11444 memset(&descriptor_write, 0, sizeof(descriptor_write));
11445 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11446 descriptor_write.dstSet = descriptorSet;
11447 descriptor_write.descriptorCount = 1;
11448 // This is a mismatched type for the layout which expects BUFFER
11449 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11450 descriptor_write.pImageInfo = &info;
11452 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11454 m_errorMonitor->VerifyFound();
11456 vkDestroySampler(m_device->device(), sampler, NULL);
11457 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11458 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11461 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
11462 // For overlapping Update, have arrayIndex exceed that of layout
11465 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11466 " binding #0 with 1 total descriptors but update of 1 descriptors "
11467 "starting at binding offset of 0 combined with update array element "
11468 "offset of 1 oversteps the size of this descriptor set.");
11470 ASSERT_NO_FATAL_FAILURE(InitState());
11471 // VkDescriptorSetObj descriptorSet(m_device);
11472 VkDescriptorPoolSize ds_type_count = {};
11473 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11474 ds_type_count.descriptorCount = 1;
11476 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11477 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11478 ds_pool_ci.pNext = NULL;
11479 ds_pool_ci.maxSets = 1;
11480 ds_pool_ci.poolSizeCount = 1;
11481 ds_pool_ci.pPoolSizes = &ds_type_count;
11483 VkDescriptorPool ds_pool;
11484 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11485 ASSERT_VK_SUCCESS(err);
11487 VkDescriptorSetLayoutBinding dsl_binding = {};
11488 dsl_binding.binding = 0;
11489 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11490 dsl_binding.descriptorCount = 1;
11491 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11492 dsl_binding.pImmutableSamplers = NULL;
11494 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11495 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11496 ds_layout_ci.pNext = NULL;
11497 ds_layout_ci.bindingCount = 1;
11498 ds_layout_ci.pBindings = &dsl_binding;
11500 VkDescriptorSetLayout ds_layout;
11501 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11502 ASSERT_VK_SUCCESS(err);
11504 VkDescriptorSet descriptorSet;
11505 VkDescriptorSetAllocateInfo alloc_info = {};
11506 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11507 alloc_info.descriptorSetCount = 1;
11508 alloc_info.descriptorPool = ds_pool;
11509 alloc_info.pSetLayouts = &ds_layout;
11510 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11511 ASSERT_VK_SUCCESS(err);
11513 // Correctly update descriptor to avoid "NOT_UPDATED" error
11514 VkDescriptorBufferInfo buff_info = {};
11515 buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test
11516 buff_info.offset = 0;
11517 buff_info.range = 1024;
11519 VkWriteDescriptorSet descriptor_write;
11520 memset(&descriptor_write, 0, sizeof(descriptor_write));
11521 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11522 descriptor_write.dstSet = descriptorSet;
11523 descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
11524 descriptor_write.descriptorCount = 1;
11525 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11526 descriptor_write.pBufferInfo = &buff_info;
11528 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11530 m_errorMonitor->VerifyFound();
11532 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11533 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11536 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
11537 // Create layout w/ count of 1 and attempt update to that layout w/ binding
11541 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2.");
11543 ASSERT_NO_FATAL_FAILURE(InitState());
11544 // VkDescriptorSetObj descriptorSet(m_device);
11545 VkDescriptorPoolSize ds_type_count = {};
11546 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11547 ds_type_count.descriptorCount = 1;
11549 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11550 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11551 ds_pool_ci.pNext = NULL;
11552 ds_pool_ci.maxSets = 1;
11553 ds_pool_ci.poolSizeCount = 1;
11554 ds_pool_ci.pPoolSizes = &ds_type_count;
11556 VkDescriptorPool ds_pool;
11557 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11558 ASSERT_VK_SUCCESS(err);
11560 VkDescriptorSetLayoutBinding dsl_binding = {};
11561 dsl_binding.binding = 0;
11562 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11563 dsl_binding.descriptorCount = 1;
11564 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11565 dsl_binding.pImmutableSamplers = NULL;
11567 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11568 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11569 ds_layout_ci.pNext = NULL;
11570 ds_layout_ci.bindingCount = 1;
11571 ds_layout_ci.pBindings = &dsl_binding;
11572 VkDescriptorSetLayout ds_layout;
11573 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11574 ASSERT_VK_SUCCESS(err);
11576 VkDescriptorSet descriptorSet;
11577 VkDescriptorSetAllocateInfo alloc_info = {};
11578 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11579 alloc_info.descriptorSetCount = 1;
11580 alloc_info.descriptorPool = ds_pool;
11581 alloc_info.pSetLayouts = &ds_layout;
11582 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11583 ASSERT_VK_SUCCESS(err);
11585 VkSamplerCreateInfo sampler_ci = {};
11586 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11587 sampler_ci.pNext = NULL;
11588 sampler_ci.magFilter = VK_FILTER_NEAREST;
11589 sampler_ci.minFilter = VK_FILTER_NEAREST;
11590 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11591 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11592 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11593 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11594 sampler_ci.mipLodBias = 1.0;
11595 sampler_ci.anisotropyEnable = VK_FALSE;
11596 sampler_ci.maxAnisotropy = 1;
11597 sampler_ci.compareEnable = VK_FALSE;
11598 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11599 sampler_ci.minLod = 1.0;
11600 sampler_ci.maxLod = 1.0;
11601 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11602 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11605 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11606 ASSERT_VK_SUCCESS(err);
11608 VkDescriptorImageInfo info = {};
11609 info.sampler = sampler;
11611 VkWriteDescriptorSet descriptor_write;
11612 memset(&descriptor_write, 0, sizeof(descriptor_write));
11613 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11614 descriptor_write.dstSet = descriptorSet;
11615 descriptor_write.dstBinding = 2;
11616 descriptor_write.descriptorCount = 1;
11617 // This is the wrong type, but out of bounds will be flagged first
11618 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11619 descriptor_write.pImageInfo = &info;
11621 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11623 m_errorMonitor->VerifyFound();
11625 vkDestroySampler(m_device->device(), sampler, NULL);
11626 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11627 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11630 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
11631 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
11635 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
11637 ASSERT_NO_FATAL_FAILURE(InitState());
11639 VkDescriptorPoolSize ds_type_count = {};
11640 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11641 ds_type_count.descriptorCount = 1;
11643 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11644 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11645 ds_pool_ci.pNext = NULL;
11646 ds_pool_ci.maxSets = 1;
11647 ds_pool_ci.poolSizeCount = 1;
11648 ds_pool_ci.pPoolSizes = &ds_type_count;
11650 VkDescriptorPool ds_pool;
11651 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11652 ASSERT_VK_SUCCESS(err);
11653 VkDescriptorSetLayoutBinding dsl_binding = {};
11654 dsl_binding.binding = 0;
11655 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11656 dsl_binding.descriptorCount = 1;
11657 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11658 dsl_binding.pImmutableSamplers = NULL;
11660 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11661 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11662 ds_layout_ci.pNext = NULL;
11663 ds_layout_ci.bindingCount = 1;
11664 ds_layout_ci.pBindings = &dsl_binding;
11666 VkDescriptorSetLayout ds_layout;
11667 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11668 ASSERT_VK_SUCCESS(err);
11670 VkDescriptorSet descriptorSet;
11671 VkDescriptorSetAllocateInfo alloc_info = {};
11672 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11673 alloc_info.descriptorSetCount = 1;
11674 alloc_info.descriptorPool = ds_pool;
11675 alloc_info.pSetLayouts = &ds_layout;
11676 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11677 ASSERT_VK_SUCCESS(err);
11679 VkSamplerCreateInfo sampler_ci = {};
11680 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11681 sampler_ci.pNext = NULL;
11682 sampler_ci.magFilter = VK_FILTER_NEAREST;
11683 sampler_ci.minFilter = VK_FILTER_NEAREST;
11684 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11685 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11686 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11687 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11688 sampler_ci.mipLodBias = 1.0;
11689 sampler_ci.anisotropyEnable = VK_FALSE;
11690 sampler_ci.maxAnisotropy = 1;
11691 sampler_ci.compareEnable = VK_FALSE;
11692 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11693 sampler_ci.minLod = 1.0;
11694 sampler_ci.maxLod = 1.0;
11695 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11696 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11698 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11699 ASSERT_VK_SUCCESS(err);
11701 VkDescriptorImageInfo info = {};
11702 info.sampler = sampler;
11704 VkWriteDescriptorSet descriptor_write;
11705 memset(&descriptor_write, 0, sizeof(descriptor_write));
11706 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
11707 descriptor_write.dstSet = descriptorSet;
11708 descriptor_write.descriptorCount = 1;
11709 // This is the wrong type, but out of bounds will be flagged first
11710 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11711 descriptor_write.pImageInfo = &info;
11713 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11715 m_errorMonitor->VerifyFound();
11717 vkDestroySampler(m_device->device(), sampler, NULL);
11718 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11719 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11722 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
11723 // Create a single Sampler descriptor and send it an invalid Sampler
11726 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11727 "Attempted write update to sampler descriptor with invalid sampler");
11729 ASSERT_NO_FATAL_FAILURE(InitState());
11730 // TODO : Farm Descriptor setup code to helper function(s) to reduce copied
11732 VkDescriptorPoolSize ds_type_count = {};
11733 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
11734 ds_type_count.descriptorCount = 1;
11736 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11737 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11738 ds_pool_ci.pNext = NULL;
11739 ds_pool_ci.maxSets = 1;
11740 ds_pool_ci.poolSizeCount = 1;
11741 ds_pool_ci.pPoolSizes = &ds_type_count;
11743 VkDescriptorPool ds_pool;
11744 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11745 ASSERT_VK_SUCCESS(err);
11747 VkDescriptorSetLayoutBinding dsl_binding = {};
11748 dsl_binding.binding = 0;
11749 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11750 dsl_binding.descriptorCount = 1;
11751 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11752 dsl_binding.pImmutableSamplers = NULL;
11754 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11755 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11756 ds_layout_ci.pNext = NULL;
11757 ds_layout_ci.bindingCount = 1;
11758 ds_layout_ci.pBindings = &dsl_binding;
11759 VkDescriptorSetLayout ds_layout;
11760 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11761 ASSERT_VK_SUCCESS(err);
11763 VkDescriptorSet descriptorSet;
11764 VkDescriptorSetAllocateInfo alloc_info = {};
11765 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11766 alloc_info.descriptorSetCount = 1;
11767 alloc_info.descriptorPool = ds_pool;
11768 alloc_info.pSetLayouts = &ds_layout;
11769 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11770 ASSERT_VK_SUCCESS(err);
11772 VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle
11774 VkDescriptorImageInfo descriptor_info;
11775 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11776 descriptor_info.sampler = sampler;
11778 VkWriteDescriptorSet descriptor_write;
11779 memset(&descriptor_write, 0, sizeof(descriptor_write));
11780 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11781 descriptor_write.dstSet = descriptorSet;
11782 descriptor_write.dstBinding = 0;
11783 descriptor_write.descriptorCount = 1;
11784 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11785 descriptor_write.pImageInfo = &descriptor_info;
11787 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11789 m_errorMonitor->VerifyFound();
11791 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11792 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11795 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
11796 // Create a single combined Image/Sampler descriptor and send it an invalid
11800 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined "
11801 "image sampler descriptor failed due "
11802 "to: Invalid VkImageView:");
11804 ASSERT_NO_FATAL_FAILURE(InitState());
11805 VkDescriptorPoolSize ds_type_count = {};
11806 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11807 ds_type_count.descriptorCount = 1;
11809 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11810 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11811 ds_pool_ci.pNext = NULL;
11812 ds_pool_ci.maxSets = 1;
11813 ds_pool_ci.poolSizeCount = 1;
11814 ds_pool_ci.pPoolSizes = &ds_type_count;
11816 VkDescriptorPool ds_pool;
11817 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11818 ASSERT_VK_SUCCESS(err);
11820 VkDescriptorSetLayoutBinding dsl_binding = {};
11821 dsl_binding.binding = 0;
11822 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11823 dsl_binding.descriptorCount = 1;
11824 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11825 dsl_binding.pImmutableSamplers = NULL;
11827 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11828 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11829 ds_layout_ci.pNext = NULL;
11830 ds_layout_ci.bindingCount = 1;
11831 ds_layout_ci.pBindings = &dsl_binding;
11832 VkDescriptorSetLayout ds_layout;
11833 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11834 ASSERT_VK_SUCCESS(err);
11836 VkDescriptorSet descriptorSet;
11837 VkDescriptorSetAllocateInfo alloc_info = {};
11838 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11839 alloc_info.descriptorSetCount = 1;
11840 alloc_info.descriptorPool = ds_pool;
11841 alloc_info.pSetLayouts = &ds_layout;
11842 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11843 ASSERT_VK_SUCCESS(err);
11845 VkSamplerCreateInfo sampler_ci = {};
11846 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11847 sampler_ci.pNext = NULL;
11848 sampler_ci.magFilter = VK_FILTER_NEAREST;
11849 sampler_ci.minFilter = VK_FILTER_NEAREST;
11850 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11851 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11852 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11853 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11854 sampler_ci.mipLodBias = 1.0;
11855 sampler_ci.anisotropyEnable = VK_FALSE;
11856 sampler_ci.maxAnisotropy = 1;
11857 sampler_ci.compareEnable = VK_FALSE;
11858 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11859 sampler_ci.minLod = 1.0;
11860 sampler_ci.maxLod = 1.0;
11861 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11862 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11865 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11866 ASSERT_VK_SUCCESS(err);
11868 VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object
11870 VkDescriptorImageInfo descriptor_info;
11871 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
11872 descriptor_info.sampler = sampler;
11873 descriptor_info.imageView = view;
11875 VkWriteDescriptorSet descriptor_write;
11876 memset(&descriptor_write, 0, sizeof(descriptor_write));
11877 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11878 descriptor_write.dstSet = descriptorSet;
11879 descriptor_write.dstBinding = 0;
11880 descriptor_write.descriptorCount = 1;
11881 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11882 descriptor_write.pImageInfo = &descriptor_info;
11884 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11886 m_errorMonitor->VerifyFound();
11888 vkDestroySampler(m_device->device(), sampler, NULL);
11889 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
11890 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11893 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
11894 // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
11898 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type "
11899 "VK_DESCRIPTOR_TYPE_SAMPLER. Types do "
11902 ASSERT_NO_FATAL_FAILURE(InitState());
11903 // VkDescriptorSetObj descriptorSet(m_device);
11904 VkDescriptorPoolSize ds_type_count[2] = {};
11905 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11906 ds_type_count[0].descriptorCount = 1;
11907 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
11908 ds_type_count[1].descriptorCount = 1;
11910 VkDescriptorPoolCreateInfo ds_pool_ci = {};
11911 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11912 ds_pool_ci.pNext = NULL;
11913 ds_pool_ci.maxSets = 1;
11914 ds_pool_ci.poolSizeCount = 2;
11915 ds_pool_ci.pPoolSizes = ds_type_count;
11917 VkDescriptorPool ds_pool;
11918 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11919 ASSERT_VK_SUCCESS(err);
11920 VkDescriptorSetLayoutBinding dsl_binding[2] = {};
11921 dsl_binding[0].binding = 0;
11922 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
11923 dsl_binding[0].descriptorCount = 1;
11924 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
11925 dsl_binding[0].pImmutableSamplers = NULL;
11926 dsl_binding[1].binding = 1;
11927 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11928 dsl_binding[1].descriptorCount = 1;
11929 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
11930 dsl_binding[1].pImmutableSamplers = NULL;
11932 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
11933 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
11934 ds_layout_ci.pNext = NULL;
11935 ds_layout_ci.bindingCount = 2;
11936 ds_layout_ci.pBindings = dsl_binding;
11938 VkDescriptorSetLayout ds_layout;
11939 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
11940 ASSERT_VK_SUCCESS(err);
11942 VkDescriptorSet descriptorSet;
11943 VkDescriptorSetAllocateInfo alloc_info = {};
11944 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11945 alloc_info.descriptorSetCount = 1;
11946 alloc_info.descriptorPool = ds_pool;
11947 alloc_info.pSetLayouts = &ds_layout;
11948 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11949 ASSERT_VK_SUCCESS(err);
11951 VkSamplerCreateInfo sampler_ci = {};
11952 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
11953 sampler_ci.pNext = NULL;
11954 sampler_ci.magFilter = VK_FILTER_NEAREST;
11955 sampler_ci.minFilter = VK_FILTER_NEAREST;
11956 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
11957 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11958 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11959 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
11960 sampler_ci.mipLodBias = 1.0;
11961 sampler_ci.anisotropyEnable = VK_FALSE;
11962 sampler_ci.maxAnisotropy = 1;
11963 sampler_ci.compareEnable = VK_FALSE;
11964 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
11965 sampler_ci.minLod = 1.0;
11966 sampler_ci.maxLod = 1.0;
11967 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
11968 sampler_ci.unnormalizedCoordinates = VK_FALSE;
11971 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11972 ASSERT_VK_SUCCESS(err);
11974 VkDescriptorImageInfo info = {};
11975 info.sampler = sampler;
11977 VkWriteDescriptorSet descriptor_write;
11978 memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
11979 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11980 descriptor_write.dstSet = descriptorSet;
11981 descriptor_write.dstBinding = 1; // SAMPLER binding from layout above
11982 descriptor_write.descriptorCount = 1;
11983 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
11984 descriptor_write.pImageInfo = &info;
11985 // This write update should succeed
11986 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11987 // Now perform a copy update that fails due to type mismatch
11988 VkCopyDescriptorSet copy_ds_update;
11989 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
11990 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
11991 copy_ds_update.srcSet = descriptorSet;
11992 copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding
11993 copy_ds_update.dstSet = descriptorSet;
11994 copy_ds_update.dstBinding = 0; // ERROR : copy to UNIFORM binding
11995 copy_ds_update.descriptorCount = 1; // copy 1 descriptor
11996 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
11998 m_errorMonitor->VerifyFound();
11999 // Now perform a copy update that fails due to binding out of bounds
12000 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
12001 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
12002 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12003 copy_ds_update.srcSet = descriptorSet;
12004 copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout
12005 copy_ds_update.dstSet = descriptorSet;
12006 copy_ds_update.dstBinding = 0;
12007 copy_ds_update.descriptorCount = 1; // Copy 1 descriptor
12008 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
12010 m_errorMonitor->VerifyFound();
12012 // Now perform a copy update that fails due to binding out of bounds
12013 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus "
12014 "update array offset of 0 and update of "
12015 "5 descriptors oversteps total number "
12016 "of descriptors in set: 2.");
12018 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet));
12019 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
12020 copy_ds_update.srcSet = descriptorSet;
12021 copy_ds_update.srcBinding = 1;
12022 copy_ds_update.dstSet = descriptorSet;
12023 copy_ds_update.dstBinding = 0;
12024 copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout)
12025 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update);
12027 m_errorMonitor->VerifyFound();
12029 vkDestroySampler(m_device->device(), sampler, NULL);
12030 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12031 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12034 TEST_F(VkLayerTest, NumSamplesMismatch) {
12035 // Create CommandBuffer where MSAA samples doesn't match RenderPass
12039 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
12041 ASSERT_NO_FATAL_FAILURE(InitState());
12042 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12043 VkDescriptorPoolSize ds_type_count = {};
12044 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12045 ds_type_count.descriptorCount = 1;
12047 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12048 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12049 ds_pool_ci.pNext = NULL;
12050 ds_pool_ci.maxSets = 1;
12051 ds_pool_ci.poolSizeCount = 1;
12052 ds_pool_ci.pPoolSizes = &ds_type_count;
12054 VkDescriptorPool ds_pool;
12055 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12056 ASSERT_VK_SUCCESS(err);
12058 VkDescriptorSetLayoutBinding dsl_binding = {};
12059 dsl_binding.binding = 0;
12060 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12061 dsl_binding.descriptorCount = 1;
12062 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12063 dsl_binding.pImmutableSamplers = NULL;
12065 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12066 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12067 ds_layout_ci.pNext = NULL;
12068 ds_layout_ci.bindingCount = 1;
12069 ds_layout_ci.pBindings = &dsl_binding;
12071 VkDescriptorSetLayout ds_layout;
12072 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12073 ASSERT_VK_SUCCESS(err);
12075 VkDescriptorSet descriptorSet;
12076 VkDescriptorSetAllocateInfo alloc_info = {};
12077 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12078 alloc_info.descriptorSetCount = 1;
12079 alloc_info.descriptorPool = ds_pool;
12080 alloc_info.pSetLayouts = &ds_layout;
12081 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12082 ASSERT_VK_SUCCESS(err);
12084 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12085 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12086 pipe_ms_state_ci.pNext = NULL;
12087 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12088 pipe_ms_state_ci.sampleShadingEnable = 0;
12089 pipe_ms_state_ci.minSampleShading = 1.0;
12090 pipe_ms_state_ci.pSampleMask = NULL;
12092 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12093 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12094 pipeline_layout_ci.pNext = NULL;
12095 pipeline_layout_ci.setLayoutCount = 1;
12096 pipeline_layout_ci.pSetLayouts = &ds_layout;
12098 VkPipelineLayout pipeline_layout;
12099 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12100 ASSERT_VK_SUCCESS(err);
12102 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12103 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12104 // but add it to be able to run on more devices
12105 VkPipelineObj pipe(m_device);
12106 pipe.AddShader(&vs);
12107 pipe.AddShader(&fs);
12108 pipe.AddColorAttachment();
12109 pipe.SetMSAA(&pipe_ms_state_ci);
12110 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12112 BeginCommandBuffer();
12113 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12115 // Render triangle (the error should trigger on the attempt to draw).
12118 // Finalize recording of the command buffer
12119 EndCommandBuffer();
12121 m_errorMonitor->VerifyFound();
12123 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12124 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12125 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12128 TEST_F(VkLayerTest, RenderPassIncompatible) {
12129 TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
12130 "Initial case is drawing with an active renderpass that's "
12131 "not compatible with the bound PSO's creation renderpass");
12134 ASSERT_NO_FATAL_FAILURE(InitState());
12135 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12137 VkDescriptorSetLayoutBinding dsl_binding = {};
12138 dsl_binding.binding = 0;
12139 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12140 dsl_binding.descriptorCount = 1;
12141 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12142 dsl_binding.pImmutableSamplers = NULL;
12144 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12145 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12146 ds_layout_ci.pNext = NULL;
12147 ds_layout_ci.bindingCount = 1;
12148 ds_layout_ci.pBindings = &dsl_binding;
12150 VkDescriptorSetLayout ds_layout;
12151 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12152 ASSERT_VK_SUCCESS(err);
12154 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12155 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12156 pipeline_layout_ci.pNext = NULL;
12157 pipeline_layout_ci.setLayoutCount = 1;
12158 pipeline_layout_ci.pSetLayouts = &ds_layout;
12160 VkPipelineLayout pipeline_layout;
12161 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12162 ASSERT_VK_SUCCESS(err);
12164 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12165 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12166 // but add it to be able to run on more devices
12167 // Create a renderpass that will be incompatible with default renderpass
12168 VkAttachmentReference attach = {};
12169 attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12170 VkAttachmentReference color_att = {};
12171 color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12172 VkSubpassDescription subpass = {};
12173 subpass.inputAttachmentCount = 1;
12174 subpass.pInputAttachments = &attach;
12175 subpass.colorAttachmentCount = 1;
12176 subpass.pColorAttachments = &color_att;
12177 VkRenderPassCreateInfo rpci = {};
12178 rpci.subpassCount = 1;
12179 rpci.pSubpasses = &subpass;
12180 rpci.attachmentCount = 1;
12181 VkAttachmentDescription attach_desc = {};
12182 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12183 // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
12184 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
12185 rpci.pAttachments = &attach_desc;
12186 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12188 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12189 VkPipelineObj pipe(m_device);
12190 pipe.AddShader(&vs);
12191 pipe.AddShader(&fs);
12192 pipe.AddColorAttachment();
12193 VkViewport view_port = {};
12194 m_viewports.push_back(view_port);
12195 pipe.SetViewport(m_viewports);
12196 VkRect2D rect = {};
12197 m_scissors.push_back(rect);
12198 pipe.SetScissor(m_scissors);
12199 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12201 VkCommandBufferInheritanceInfo cbii = {};
12202 cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12203 cbii.renderPass = rp;
12205 VkCommandBufferBeginInfo cbbi = {};
12206 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12207 cbbi.pInheritanceInfo = &cbii;
12208 vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
12209 VkRenderPassBeginInfo rpbi = {};
12210 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
12211 rpbi.framebuffer = m_framebuffer;
12212 rpbi.renderPass = rp;
12213 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
12214 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12216 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline ");
12217 // Render triangle (the error should trigger on the attempt to draw).
12220 // Finalize recording of the command buffer
12221 EndCommandBuffer();
12223 m_errorMonitor->VerifyFound();
12225 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12226 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12227 vkDestroyRenderPass(m_device->device(), rp, NULL);
12230 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
12231 // Create Pipeline where the number of blend attachments doesn't match the
12232 // number of color attachments. In this case, we don't add any color
12233 // blend attachments even though we have a color attachment.
12236 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12237 "Render pass subpass 0 mismatch with blending state defined and blend state attachment");
12239 ASSERT_NO_FATAL_FAILURE(InitState());
12240 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12241 VkDescriptorPoolSize ds_type_count = {};
12242 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12243 ds_type_count.descriptorCount = 1;
12245 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12246 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12247 ds_pool_ci.pNext = NULL;
12248 ds_pool_ci.maxSets = 1;
12249 ds_pool_ci.poolSizeCount = 1;
12250 ds_pool_ci.pPoolSizes = &ds_type_count;
12252 VkDescriptorPool ds_pool;
12253 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12254 ASSERT_VK_SUCCESS(err);
12256 VkDescriptorSetLayoutBinding dsl_binding = {};
12257 dsl_binding.binding = 0;
12258 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12259 dsl_binding.descriptorCount = 1;
12260 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12261 dsl_binding.pImmutableSamplers = NULL;
12263 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12264 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12265 ds_layout_ci.pNext = NULL;
12266 ds_layout_ci.bindingCount = 1;
12267 ds_layout_ci.pBindings = &dsl_binding;
12269 VkDescriptorSetLayout ds_layout;
12270 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12271 ASSERT_VK_SUCCESS(err);
12273 VkDescriptorSet descriptorSet;
12274 VkDescriptorSetAllocateInfo alloc_info = {};
12275 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12276 alloc_info.descriptorSetCount = 1;
12277 alloc_info.descriptorPool = ds_pool;
12278 alloc_info.pSetLayouts = &ds_layout;
12279 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12280 ASSERT_VK_SUCCESS(err);
12282 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12283 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12284 pipe_ms_state_ci.pNext = NULL;
12285 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12286 pipe_ms_state_ci.sampleShadingEnable = 0;
12287 pipe_ms_state_ci.minSampleShading = 1.0;
12288 pipe_ms_state_ci.pSampleMask = NULL;
12290 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12291 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12292 pipeline_layout_ci.pNext = NULL;
12293 pipeline_layout_ci.setLayoutCount = 1;
12294 pipeline_layout_ci.pSetLayouts = &ds_layout;
12296 VkPipelineLayout pipeline_layout;
12297 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12298 ASSERT_VK_SUCCESS(err);
12300 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12301 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12302 // but add it to be able to run on more devices
12303 VkPipelineObj pipe(m_device);
12304 pipe.AddShader(&vs);
12305 pipe.AddShader(&fs);
12306 pipe.SetMSAA(&pipe_ms_state_ci);
12307 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12309 BeginCommandBuffer();
12310 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12312 // Render triangle (the error should trigger on the attempt to draw).
12315 // Finalize recording of the command buffer
12316 EndCommandBuffer();
12318 m_errorMonitor->VerifyFound();
12320 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12321 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12322 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12325 TEST_F(VkLayerTest, MissingClearAttachment) {
12326 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
12327 "structure passed to vkCmdClearAttachments");
12328 ASSERT_NO_FATAL_FAILURE(InitState());
12329 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12330 "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored");
12332 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
12333 m_errorMonitor->VerifyFound();
12336 TEST_F(VkLayerTest, ClearCmdNoDraw) {
12337 // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
12338 // to issuing a Draw
12341 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12342 "vkCmdClearAttachments() issued on CB object ");
12344 ASSERT_NO_FATAL_FAILURE(InitState());
12345 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12347 VkDescriptorPoolSize ds_type_count = {};
12348 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12349 ds_type_count.descriptorCount = 1;
12351 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12352 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12353 ds_pool_ci.pNext = NULL;
12354 ds_pool_ci.maxSets = 1;
12355 ds_pool_ci.poolSizeCount = 1;
12356 ds_pool_ci.pPoolSizes = &ds_type_count;
12358 VkDescriptorPool ds_pool;
12359 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12360 ASSERT_VK_SUCCESS(err);
12362 VkDescriptorSetLayoutBinding dsl_binding = {};
12363 dsl_binding.binding = 0;
12364 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12365 dsl_binding.descriptorCount = 1;
12366 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12367 dsl_binding.pImmutableSamplers = NULL;
12369 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12370 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12371 ds_layout_ci.pNext = NULL;
12372 ds_layout_ci.bindingCount = 1;
12373 ds_layout_ci.pBindings = &dsl_binding;
12375 VkDescriptorSetLayout ds_layout;
12376 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12377 ASSERT_VK_SUCCESS(err);
12379 VkDescriptorSet descriptorSet;
12380 VkDescriptorSetAllocateInfo alloc_info = {};
12381 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12382 alloc_info.descriptorSetCount = 1;
12383 alloc_info.descriptorPool = ds_pool;
12384 alloc_info.pSetLayouts = &ds_layout;
12385 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12386 ASSERT_VK_SUCCESS(err);
12388 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12389 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12390 pipe_ms_state_ci.pNext = NULL;
12391 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
12392 pipe_ms_state_ci.sampleShadingEnable = 0;
12393 pipe_ms_state_ci.minSampleShading = 1.0;
12394 pipe_ms_state_ci.pSampleMask = NULL;
12396 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12397 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12398 pipeline_layout_ci.pNext = NULL;
12399 pipeline_layout_ci.setLayoutCount = 1;
12400 pipeline_layout_ci.pSetLayouts = &ds_layout;
12402 VkPipelineLayout pipeline_layout;
12403 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12404 ASSERT_VK_SUCCESS(err);
12406 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12407 // We shouldn't need a fragment shader but add it to be able to run
12409 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12411 VkPipelineObj pipe(m_device);
12412 pipe.AddShader(&vs);
12413 pipe.AddShader(&fs);
12414 pipe.SetMSAA(&pipe_ms_state_ci);
12415 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12417 BeginCommandBuffer();
12419 // Main thing we care about for this test is that the VkImage obj we're
12420 // clearing matches Color Attachment of FB
12421 // Also pass down other dummy params to keep driver and paramchecker happy
12422 VkClearAttachment color_attachment;
12423 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12424 color_attachment.clearValue.color.float32[0] = 1.0;
12425 color_attachment.clearValue.color.float32[1] = 1.0;
12426 color_attachment.clearValue.color.float32[2] = 1.0;
12427 color_attachment.clearValue.color.float32[3] = 1.0;
12428 color_attachment.colorAttachment = 0;
12429 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}};
12431 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect);
12433 m_errorMonitor->VerifyFound();
12435 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12436 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12437 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12440 TEST_F(VkLayerTest, VtxBufferBadIndex) {
12443 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12444 "but no vertex buffers are attached to this Pipeline State Object");
12446 ASSERT_NO_FATAL_FAILURE(InitState());
12447 ASSERT_NO_FATAL_FAILURE(InitViewport());
12448 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12450 VkDescriptorPoolSize ds_type_count = {};
12451 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12452 ds_type_count.descriptorCount = 1;
12454 VkDescriptorPoolCreateInfo ds_pool_ci = {};
12455 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12456 ds_pool_ci.pNext = NULL;
12457 ds_pool_ci.maxSets = 1;
12458 ds_pool_ci.poolSizeCount = 1;
12459 ds_pool_ci.pPoolSizes = &ds_type_count;
12461 VkDescriptorPool ds_pool;
12462 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12463 ASSERT_VK_SUCCESS(err);
12465 VkDescriptorSetLayoutBinding dsl_binding = {};
12466 dsl_binding.binding = 0;
12467 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12468 dsl_binding.descriptorCount = 1;
12469 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12470 dsl_binding.pImmutableSamplers = NULL;
12472 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
12473 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
12474 ds_layout_ci.pNext = NULL;
12475 ds_layout_ci.bindingCount = 1;
12476 ds_layout_ci.pBindings = &dsl_binding;
12478 VkDescriptorSetLayout ds_layout;
12479 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
12480 ASSERT_VK_SUCCESS(err);
12482 VkDescriptorSet descriptorSet;
12483 VkDescriptorSetAllocateInfo alloc_info = {};
12484 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12485 alloc_info.descriptorSetCount = 1;
12486 alloc_info.descriptorPool = ds_pool;
12487 alloc_info.pSetLayouts = &ds_layout;
12488 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12489 ASSERT_VK_SUCCESS(err);
12491 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12492 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12493 pipe_ms_state_ci.pNext = NULL;
12494 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12495 pipe_ms_state_ci.sampleShadingEnable = 0;
12496 pipe_ms_state_ci.minSampleShading = 1.0;
12497 pipe_ms_state_ci.pSampleMask = NULL;
12499 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12500 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12501 pipeline_layout_ci.pNext = NULL;
12502 pipeline_layout_ci.setLayoutCount = 1;
12503 pipeline_layout_ci.pSetLayouts = &ds_layout;
12504 VkPipelineLayout pipeline_layout;
12506 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12507 ASSERT_VK_SUCCESS(err);
12509 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12510 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader
12511 // but add it to be able to run on more devices
12512 VkPipelineObj pipe(m_device);
12513 pipe.AddShader(&vs);
12514 pipe.AddShader(&fs);
12515 pipe.AddColorAttachment();
12516 pipe.SetMSAA(&pipe_ms_state_ci);
12517 pipe.SetViewport(m_viewports);
12518 pipe.SetScissor(m_scissors);
12519 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12521 BeginCommandBuffer();
12522 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12523 // Don't care about actual data, just need to get to draw to flag error
12524 static const float vbo_data[3] = {1.f, 0.f, 1.f};
12525 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data);
12526 BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
12529 m_errorMonitor->VerifyFound();
12531 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12532 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
12533 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12536 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
12537 TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call."
12538 "Use invalid Queue Family Index in vkCreateDevice");
12539 ASSERT_NO_FATAL_FAILURE(InitState());
12541 const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() "
12542 "w/ pPhysicalDeviceCount value ";
12544 const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid "
12545 "queueFamilyIndex ";
12547 const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #";
12549 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message);
12550 // The following test fails with recent NVidia drivers.
12551 // By the time core_validation is reached, the NVidia
12552 // driver has sanitized the invalid condition and core_validation
12553 // is not introduced to the failure condition. This is not the case
12554 // with AMD and Mesa drivers. Futher investigation is required
12555 // uint32_t count = static_cast<uint32_t>(~0);
12556 // VkPhysicalDevice physical_device;
12557 // vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
12558 // m_errorMonitor->VerifyFound();
12560 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message);
12561 float queue_priority = 0.0;
12563 VkDeviceQueueCreateInfo queue_create_info = {};
12564 queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
12565 queue_create_info.queueCount = 1;
12566 queue_create_info.pQueuePriorities = &queue_priority;
12567 queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
12569 VkPhysicalDeviceFeatures features = m_device->phy().features();
12570 VkDevice testDevice;
12571 VkDeviceCreateInfo device_create_info = {};
12572 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
12573 device_create_info.queueCreateInfoCount = 1;
12574 device_create_info.pQueueCreateInfos = &queue_create_info;
12575 device_create_info.pEnabledFeatures = &features;
12576 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12577 m_errorMonitor->VerifyFound();
12579 queue_create_info.queueFamilyIndex = 1;
12581 unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
12582 VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
12583 for (unsigned i = 0; i < feature_count; i++) {
12584 if (VK_FALSE == feature_array[i]) {
12585 feature_array[i] = VK_TRUE;
12586 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message);
12587 device_create_info.pEnabledFeatures = &features;
12588 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
12589 m_errorMonitor->VerifyFound();
12595 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) {
12596 TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call."
12597 "End a command buffer with a query still in progress.");
12599 const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one "
12600 "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both "
12603 const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
12605 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index);
12607 ASSERT_NO_FATAL_FAILURE(InitState());
12610 VkEventCreateInfo event_create_info{};
12611 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12612 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12614 VkQueue queue = VK_NULL_HANDLE;
12615 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
12617 BeginCommandBuffer();
12619 VkImageObj image(m_device);
12620 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12621 ASSERT_TRUE(image.initialized());
12622 VkImageMemoryBarrier img_barrier = {};
12623 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
12624 img_barrier.pNext = NULL;
12625 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
12626 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
12627 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12628 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12629 img_barrier.image = image.handle();
12630 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
12632 // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies
12633 // that layer validation catches the case when it is not.
12634 img_barrier.dstQueueFamilyIndex = 0;
12635 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12636 img_barrier.subresourceRange.baseArrayLayer = 0;
12637 img_barrier.subresourceRange.baseMipLevel = 0;
12638 img_barrier.subresourceRange.layerCount = 1;
12639 img_barrier.subresourceRange.levelCount = 1;
12640 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
12641 nullptr, 0, nullptr, 1, &img_barrier);
12642 m_errorMonitor->VerifyFound();
12644 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
12646 VkQueryPool query_pool;
12647 VkQueryPoolCreateInfo query_pool_create_info = {};
12648 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
12649 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
12650 query_pool_create_info.queryCount = 1;
12651 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12653 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
12654 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12656 vkEndCommandBuffer(m_commandBuffer->handle());
12657 m_errorMonitor->VerifyFound();
12659 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
12660 vkDestroyEvent(m_device->device(), event, nullptr);
12663 TEST_F(VkLayerTest, VertexBufferInvalid) {
12664 TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
12665 "delete a buffer twice, use an invalid offset for each "
12666 "buffer type, and attempt to bind a null buffer");
12668 const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
12669 "using deleted buffer ";
12670 const char *double_destroy_message = "Cannot free buffer 0x";
12671 const char *invalid_offset_message = "vkBindBufferMemory(): "
12672 "memoryOffset is 0x";
12673 const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
12674 "storage memoryOffset "
12676 const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
12677 "texel memoryOffset "
12679 const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
12680 "uniform memoryOffset "
12682 const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
12684 const char *free_invalid_buffer_message = "Request to delete memory "
12687 ASSERT_NO_FATAL_FAILURE(InitState());
12688 ASSERT_NO_FATAL_FAILURE(InitViewport());
12689 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12691 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
12692 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
12693 pipe_ms_state_ci.pNext = NULL;
12694 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
12695 pipe_ms_state_ci.sampleShadingEnable = 0;
12696 pipe_ms_state_ci.minSampleShading = 1.0;
12697 pipe_ms_state_ci.pSampleMask = nullptr;
12699 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12700 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12701 VkPipelineLayout pipeline_layout;
12703 VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout);
12704 ASSERT_VK_SUCCESS(err);
12706 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12707 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12708 VkPipelineObj pipe(m_device);
12709 pipe.AddShader(&vs);
12710 pipe.AddShader(&fs);
12711 pipe.AddColorAttachment();
12712 pipe.SetMSAA(&pipe_ms_state_ci);
12713 pipe.SetViewport(m_viewports);
12714 pipe.SetScissor(m_scissors);
12715 pipe.CreateVKPipeline(pipeline_layout, renderPass());
12717 BeginCommandBuffer();
12718 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12721 // Create and bind a vertex buffer in a reduced scope, which will cause
12722 // it to be deleted upon leaving this scope
12723 const float vbo_data[3] = {1.f, 0.f, 1.f};
12724 VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data);
12725 draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
12726 draw_verticies.AddVertexInputToPipe(pipe);
12731 EndCommandBuffer();
12733 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
12734 QueueCommandBuffer(false);
12735 m_errorMonitor->VerifyFound();
12738 // Create and bind a vertex buffer in a reduced scope, and delete it
12739 // twice, the second through the destructor
12740 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
12741 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message);
12742 buffer_test.TestDoubleDestroy();
12744 m_errorMonitor->VerifyFound();
12746 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
12747 // Create and bind a memory buffer with an invalid offset.
12748 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
12749 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
12751 m_errorMonitor->VerifyFound();
12754 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
12755 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
12756 // Create and bind a memory buffer with an invalid offset again,
12757 // but look for a texel buffer message.
12758 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
12759 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12761 m_errorMonitor->VerifyFound();
12764 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
12765 // Create and bind a memory buffer with an invalid offset again, but
12766 // look for a uniform buffer message.
12767 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
12768 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12770 m_errorMonitor->VerifyFound();
12773 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
12774 // Create and bind a memory buffer with an invalid offset again, but
12775 // look for a storage buffer message.
12776 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
12777 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
12779 m_errorMonitor->VerifyFound();
12783 // Attempt to bind a null buffer.
12784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message);
12785 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer);
12787 m_errorMonitor->VerifyFound();
12791 // Attempt to use an invalid handle to delete a buffer.
12792 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message);
12793 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
12796 m_errorMonitor->VerifyFound();
12798 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
12801 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
12802 TEST_F(VkLayerTest, InvalidImageLayout) {
12803 TEST_DESCRIPTION("Hit all possible validation checks associated with the "
12804 "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having"
12805 "images in the wrong layout when they're copied or transitioned.");
12806 // 3 in ValidateCmdBufImageLayouts
12807 // * -1 Attempt to submit cmd buf w/ deleted image
12808 // * -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
12809 // * -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
12810 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12811 "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
12813 ASSERT_NO_FATAL_FAILURE(InitState());
12814 // Create src & dst images to use for copy operations
12818 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
12819 const int32_t tex_width = 32;
12820 const int32_t tex_height = 32;
12822 VkImageCreateInfo image_create_info = {};
12823 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
12824 image_create_info.pNext = NULL;
12825 image_create_info.imageType = VK_IMAGE_TYPE_2D;
12826 image_create_info.format = tex_format;
12827 image_create_info.extent.width = tex_width;
12828 image_create_info.extent.height = tex_height;
12829 image_create_info.extent.depth = 1;
12830 image_create_info.mipLevels = 1;
12831 image_create_info.arrayLayers = 4;
12832 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
12833 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
12834 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
12835 image_create_info.flags = 0;
12837 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
12838 ASSERT_VK_SUCCESS(err);
12839 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
12840 ASSERT_VK_SUCCESS(err);
12842 BeginCommandBuffer();
12843 VkImageCopy copyRegion;
12844 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12845 copyRegion.srcSubresource.mipLevel = 0;
12846 copyRegion.srcSubresource.baseArrayLayer = 0;
12847 copyRegion.srcSubresource.layerCount = 1;
12848 copyRegion.srcOffset.x = 0;
12849 copyRegion.srcOffset.y = 0;
12850 copyRegion.srcOffset.z = 0;
12851 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12852 copyRegion.dstSubresource.mipLevel = 0;
12853 copyRegion.dstSubresource.baseArrayLayer = 0;
12854 copyRegion.dstSubresource.layerCount = 1;
12855 copyRegion.dstOffset.x = 0;
12856 copyRegion.dstOffset.y = 0;
12857 copyRegion.dstOffset.z = 0;
12858 copyRegion.extent.width = 1;
12859 copyRegion.extent.height = 1;
12860 copyRegion.extent.depth = 1;
12861 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12862 m_errorMonitor->VerifyFound();
12863 // Now cause error due to src image layout changing
12864 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is "
12865 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12866 "layout VK_IMAGE_LAYOUT_GENERAL.");
12867 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12868 m_errorMonitor->VerifyFound();
12869 // Final src error is due to bad layout type
12870 m_errorMonitor->SetDesiredFailureMsg(
12871 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12872 "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL.");
12873 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12874 m_errorMonitor->VerifyFound();
12875 // Now verify same checks for dst
12876 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12877 "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
12878 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
12879 m_errorMonitor->VerifyFound();
12880 // Now cause error due to src image layout changing
12881 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is "
12882 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current "
12883 "layout VK_IMAGE_LAYOUT_GENERAL.");
12884 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region);
12885 m_errorMonitor->VerifyFound();
12886 m_errorMonitor->SetDesiredFailureMsg(
12887 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12888 "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL.");
12889 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region);
12890 m_errorMonitor->VerifyFound();
12891 // Now cause error due to bad image layout transition in PipelineBarrier
12892 VkImageMemoryBarrier image_barrier[1] = {};
12893 image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12894 image_barrier[0].image = src_image;
12895 image_barrier[0].subresourceRange.layerCount = 2;
12896 image_barrier[0].subresourceRange.levelCount = 2;
12897 image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12898 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from "
12899 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when "
12900 "current layout is VK_IMAGE_LAYOUT_GENERAL.");
12901 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
12902 NULL, 0, NULL, 1, image_barrier);
12903 m_errorMonitor->VerifyFound();
12905 // Finally some layout errors at RenderPass create time
12906 // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
12907 VkAttachmentReference attach = {};
12908 // perf warning for GENERAL layout w/ non-DS input attachment
12909 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12910 VkSubpassDescription subpass = {};
12911 subpass.inputAttachmentCount = 1;
12912 subpass.pInputAttachments = &attach;
12913 VkRenderPassCreateInfo rpci = {};
12914 rpci.subpassCount = 1;
12915 rpci.pSubpasses = &subpass;
12916 rpci.attachmentCount = 1;
12917 VkAttachmentDescription attach_desc = {};
12918 attach_desc.format = VK_FORMAT_UNDEFINED;
12919 rpci.pAttachments = &attach_desc;
12920 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
12922 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12923 "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
12924 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12925 m_errorMonitor->VerifyFound();
12926 // error w/ non-general layout
12927 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12929 m_errorMonitor->SetDesiredFailureMsg(
12930 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12931 "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
12932 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12933 m_errorMonitor->VerifyFound();
12934 subpass.inputAttachmentCount = 0;
12935 subpass.colorAttachmentCount = 1;
12936 subpass.pColorAttachments = &attach;
12937 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12938 // perf warning for GENERAL layout on color attachment
12939 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12940 "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
12941 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12942 m_errorMonitor->VerifyFound();
12943 // error w/ non-color opt or GENERAL layout for color attachment
12944 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12945 m_errorMonitor->SetDesiredFailureMsg(
12946 VK_DEBUG_REPORT_ERROR_BIT_EXT,
12947 "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
12948 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12949 m_errorMonitor->VerifyFound();
12950 subpass.colorAttachmentCount = 0;
12951 subpass.pDepthStencilAttachment = &attach;
12952 attach.layout = VK_IMAGE_LAYOUT_GENERAL;
12953 // perf warning for GENERAL layout on DS attachment
12954 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
12955 "GENERAL layout for depth attachment may not give optimal performance.");
12956 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12957 m_errorMonitor->VerifyFound();
12958 // error w/ non-ds opt or GENERAL layout for color attachment
12959 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12960 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12961 "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
12962 "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
12963 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12964 m_errorMonitor->VerifyFound();
12965 // For this error we need a valid renderpass so create default one
12966 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12967 attach.attachment = 0;
12968 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
12969 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
12970 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
12971 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
12972 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
12973 // Can't do a CLEAR load on READ_ONLY initialLayout
12974 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
12975 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
12976 attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
12977 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout "
12978 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_"
12980 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
12981 m_errorMonitor->VerifyFound();
12983 vkDestroyImage(m_device->device(), src_image, NULL);
12984 vkDestroyImage(m_device->device(), dst_image, NULL);
12987 TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
12988 TEST_DESCRIPTION("Positive test where we create a renderpass with an "
12989 "attachment that uses LOAD_OP_CLEAR, the first subpass "
12990 "has a valid layout, and a second subpass then uses a "
12991 "valid *READ_ONLY* layout.");
12992 m_errorMonitor->ExpectSuccess();
12993 ASSERT_NO_FATAL_FAILURE(InitState());
12995 VkAttachmentReference attach[2] = {};
12996 attach[0].attachment = 0;
12997 attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
12998 attach[1].attachment = 0;
12999 attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13000 VkSubpassDescription subpasses[2] = {};
13001 // First subpass clears DS attach on load
13002 subpasses[0].pDepthStencilAttachment = &attach[0];
13003 // 2nd subpass reads in DS as input attachment
13004 subpasses[1].inputAttachmentCount = 1;
13005 subpasses[1].pInputAttachments = &attach[1];
13006 VkAttachmentDescription attach_desc = {};
13007 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
13008 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
13009 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
13010 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
13011 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13012 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
13013 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
13014 attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
13015 VkRenderPassCreateInfo rpci = {};
13016 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
13017 rpci.attachmentCount = 1;
13018 rpci.pAttachments = &attach_desc;
13019 rpci.subpassCount = 2;
13020 rpci.pSubpasses = subpasses;
13022 // Now create RenderPass and verify no errors
13024 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
13025 m_errorMonitor->VerifyNotFound();
13027 vkDestroyRenderPass(m_device->device(), rp, NULL);
13030 TEST_F(VkLayerTest, SimultaneousUse) {
13031 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13032 "in primary and secondary command buffers.");
13034 ASSERT_NO_FATAL_FAILURE(InitState());
13035 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13037 const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
13038 const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
13039 "will cause primary command buffer";
13041 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
13042 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13043 command_buffer_allocate_info.commandPool = m_commandPool;
13044 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13045 command_buffer_allocate_info.commandBufferCount = 1;
13047 VkCommandBuffer secondary_command_buffer;
13048 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
13049 VkCommandBufferBeginInfo command_buffer_begin_info = {};
13050 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
13051 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
13052 command_buffer_inheritance_info.renderPass = m_renderPass;
13053 command_buffer_inheritance_info.framebuffer = m_framebuffer;
13054 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13055 command_buffer_begin_info.flags =
13056 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13057 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
13059 vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
13060 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13061 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13062 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13063 vkEndCommandBuffer(secondary_command_buffer);
13065 VkSubmitInfo submit_info = {};
13066 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13067 submit_info.commandBufferCount = 1;
13068 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13069 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13071 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13072 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1);
13074 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13075 m_errorMonitor->VerifyFound();
13076 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13077 vkEndCommandBuffer(m_commandBuffer->handle());
13079 m_errorMonitor->SetDesiredFailureMsg(0, "");
13080 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13082 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
13083 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info);
13084 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13086 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2);
13087 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
13088 m_errorMonitor->VerifyFound();
13089 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
13090 vkEndCommandBuffer(m_commandBuffer->handle());
13093 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
13094 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state "
13095 "in primary and secondary command buffers. "
13096 "Delete objects that are inuse. Call VkQueueSubmit "
13097 "with an event that has been deleted.");
13099 ASSERT_NO_FATAL_FAILURE(InitState());
13100 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13102 const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x";
13103 const char *cannot_delete_event_message = "Cannot delete event 0x";
13104 const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x";
13105 const char *cannot_destroy_fence_message = "Fence 0x";
13107 BeginCommandBuffer();
13110 VkEventCreateInfo event_create_info = {};
13111 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
13112 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13113 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13115 EndCommandBuffer();
13116 vkDestroyEvent(m_device->device(), event, nullptr);
13118 VkSubmitInfo submit_info = {};
13119 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13120 submit_info.commandBufferCount = 1;
13121 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13122 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message);
13123 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13124 m_errorMonitor->VerifyFound();
13126 m_errorMonitor->SetDesiredFailureMsg(0, "");
13127 vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13129 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
13131 VkSemaphoreCreateInfo semaphore_create_info = {};
13132 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13133 VkSemaphore semaphore;
13134 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13135 VkFenceCreateInfo fence_create_info = {};
13136 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13138 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13140 VkDescriptorPoolSize descriptor_pool_type_count = {};
13141 descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13142 descriptor_pool_type_count.descriptorCount = 1;
13144 VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
13145 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13146 descriptor_pool_create_info.maxSets = 1;
13147 descriptor_pool_create_info.poolSizeCount = 1;
13148 descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
13149 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
13151 VkDescriptorPool descriptorset_pool;
13152 ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
13154 VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
13155 descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13156 descriptorset_layout_binding.descriptorCount = 1;
13157 descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
13159 VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
13160 descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13161 descriptorset_layout_create_info.bindingCount = 1;
13162 descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
13164 VkDescriptorSetLayout descriptorset_layout;
13166 vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
13168 VkDescriptorSet descriptorset;
13169 VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
13170 descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13171 descriptorset_allocate_info.descriptorSetCount = 1;
13172 descriptorset_allocate_info.descriptorPool = descriptorset_pool;
13173 descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
13174 ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
13176 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
13178 VkDescriptorBufferInfo buffer_info = {};
13179 buffer_info.buffer = buffer_test.GetBuffer();
13180 buffer_info.offset = 0;
13181 buffer_info.range = 1024;
13183 VkWriteDescriptorSet write_descriptor_set = {};
13184 write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13185 write_descriptor_set.dstSet = descriptorset;
13186 write_descriptor_set.descriptorCount = 1;
13187 write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13188 write_descriptor_set.pBufferInfo = &buffer_info;
13190 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
13192 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13193 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13195 VkPipelineObj pipe(m_device);
13196 pipe.AddColorAttachment();
13197 pipe.AddShader(&vs);
13198 pipe.AddShader(&fs);
13200 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
13201 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13202 pipeline_layout_create_info.setLayoutCount = 1;
13203 pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
13205 VkPipelineLayout pipeline_layout;
13206 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
13208 pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
13210 BeginCommandBuffer();
13211 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
13213 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13214 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13215 &descriptorset, 0, NULL);
13217 EndCommandBuffer();
13219 submit_info.signalSemaphoreCount = 1;
13220 submit_info.pSignalSemaphores = &semaphore;
13221 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
13223 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message);
13224 vkDestroyEvent(m_device->device(), event, nullptr);
13225 m_errorMonitor->VerifyFound();
13227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message);
13228 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13229 m_errorMonitor->VerifyFound();
13231 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message);
13232 vkDestroyFence(m_device->device(), fence, nullptr);
13233 m_errorMonitor->VerifyFound();
13235 vkQueueWaitIdle(m_device->m_queue);
13236 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13237 vkDestroyFence(m_device->device(), fence, nullptr);
13238 vkDestroyEvent(m_device->device(), event, nullptr);
13239 vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
13240 vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
13241 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
13244 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
13245 TEST_DESCRIPTION("Delete in-use query pool.");
13247 ASSERT_NO_FATAL_FAILURE(InitState());
13248 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13250 VkQueryPool query_pool;
13251 VkQueryPoolCreateInfo query_pool_ci{};
13252 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
13253 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
13254 query_pool_ci.queryCount = 1;
13255 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13256 BeginCommandBuffer();
13257 // Reset query pool to create binding with cmd buffer
13258 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13260 EndCommandBuffer();
13262 VkSubmitInfo submit_info = {};
13263 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13264 submit_info.commandBufferCount = 1;
13265 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13266 // Submit cmd buffer and then destroy query pool while in-flight
13267 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13269 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x");
13270 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13271 m_errorMonitor->VerifyFound();
13273 vkQueueWaitIdle(m_device->m_queue);
13274 // Now that cmd buffer done we can safely destroy query_pool
13275 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
13278 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
13279 TEST_DESCRIPTION("Delete in-use pipeline.");
13281 ASSERT_NO_FATAL_FAILURE(InitState());
13282 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13284 // Empty pipeline layout used for binding PSO
13285 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13286 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13287 pipeline_layout_ci.setLayoutCount = 0;
13288 pipeline_layout_ci.pSetLayouts = NULL;
13290 VkPipelineLayout pipeline_layout;
13291 VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout);
13292 ASSERT_VK_SUCCESS(err);
13294 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x");
13295 // Create PSO to be used for draw-time errors below
13296 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13297 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13298 // Store pipeline handle so we can actually delete it before test finishes
13299 VkPipeline delete_this_pipeline;
13300 { // Scope pipeline so it will be auto-deleted
13301 VkPipelineObj pipe(m_device);
13302 pipe.AddShader(&vs);
13303 pipe.AddShader(&fs);
13304 pipe.AddColorAttachment();
13305 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13306 delete_this_pipeline = pipe.handle();
13308 BeginCommandBuffer();
13309 // Bind pipeline to cmd buffer
13310 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13312 EndCommandBuffer();
13314 VkSubmitInfo submit_info = {};
13315 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13316 submit_info.commandBufferCount = 1;
13317 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13318 // Submit cmd buffer and then pipeline destroyed while in-flight
13319 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13320 } // Pipeline deletion triggered here
13321 m_errorMonitor->VerifyFound();
13322 // Make sure queue finished and then actually delete pipeline
13323 vkQueueWaitIdle(m_device->m_queue);
13324 vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
13325 vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
13328 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
13329 TEST_DESCRIPTION("Delete in-use imageView.");
13331 ASSERT_NO_FATAL_FAILURE(InitState());
13332 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13334 VkDescriptorPoolSize ds_type_count;
13335 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13336 ds_type_count.descriptorCount = 1;
13338 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13339 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13340 ds_pool_ci.maxSets = 1;
13341 ds_pool_ci.poolSizeCount = 1;
13342 ds_pool_ci.pPoolSizes = &ds_type_count;
13344 VkDescriptorPool ds_pool;
13345 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13346 ASSERT_VK_SUCCESS(err);
13348 VkSamplerCreateInfo sampler_ci = {};
13349 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13350 sampler_ci.pNext = NULL;
13351 sampler_ci.magFilter = VK_FILTER_NEAREST;
13352 sampler_ci.minFilter = VK_FILTER_NEAREST;
13353 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13354 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13355 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13356 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13357 sampler_ci.mipLodBias = 1.0;
13358 sampler_ci.anisotropyEnable = VK_FALSE;
13359 sampler_ci.maxAnisotropy = 1;
13360 sampler_ci.compareEnable = VK_FALSE;
13361 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13362 sampler_ci.minLod = 1.0;
13363 sampler_ci.maxLod = 1.0;
13364 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13365 sampler_ci.unnormalizedCoordinates = VK_FALSE;
13368 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13369 ASSERT_VK_SUCCESS(err);
13371 VkDescriptorSetLayoutBinding layout_binding;
13372 layout_binding.binding = 0;
13373 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13374 layout_binding.descriptorCount = 1;
13375 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13376 layout_binding.pImmutableSamplers = NULL;
13378 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13379 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13380 ds_layout_ci.bindingCount = 1;
13381 ds_layout_ci.pBindings = &layout_binding;
13382 VkDescriptorSetLayout ds_layout;
13383 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13384 ASSERT_VK_SUCCESS(err);
13386 VkDescriptorSetAllocateInfo alloc_info = {};
13387 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13388 alloc_info.descriptorSetCount = 1;
13389 alloc_info.descriptorPool = ds_pool;
13390 alloc_info.pSetLayouts = &ds_layout;
13391 VkDescriptorSet descriptor_set;
13392 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13393 ASSERT_VK_SUCCESS(err);
13395 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13396 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13397 pipeline_layout_ci.pNext = NULL;
13398 pipeline_layout_ci.setLayoutCount = 1;
13399 pipeline_layout_ci.pSetLayouts = &ds_layout;
13401 VkPipelineLayout pipeline_layout;
13402 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13403 ASSERT_VK_SUCCESS(err);
13405 VkImageObj image(m_device);
13406 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13407 ASSERT_TRUE(image.initialized());
13410 VkImageViewCreateInfo ivci = {};
13411 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13412 ivci.image = image.handle();
13413 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13414 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13415 ivci.subresourceRange.layerCount = 1;
13416 ivci.subresourceRange.baseMipLevel = 0;
13417 ivci.subresourceRange.levelCount = 1;
13418 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13420 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13421 ASSERT_VK_SUCCESS(err);
13423 VkDescriptorImageInfo image_info{};
13424 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13425 image_info.imageView = view;
13426 image_info.sampler = sampler;
13428 VkWriteDescriptorSet descriptor_write = {};
13429 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13430 descriptor_write.dstSet = descriptor_set;
13431 descriptor_write.dstBinding = 0;
13432 descriptor_write.descriptorCount = 1;
13433 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13434 descriptor_write.pImageInfo = &image_info;
13436 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13438 // Create PSO to use the sampler
13439 char const *vsSource = "#version 450\n"
13441 "out gl_PerVertex { \n"
13442 " vec4 gl_Position;\n"
13445 " gl_Position = vec4(1);\n"
13447 char const *fsSource = "#version 450\n"
13449 "layout(set=0, binding=0) uniform sampler2D s;\n"
13450 "layout(location=0) out vec4 x;\n"
13452 " x = texture(s, vec2(1));\n"
13454 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13455 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13456 VkPipelineObj pipe(m_device);
13457 pipe.AddShader(&vs);
13458 pipe.AddShader(&fs);
13459 pipe.AddColorAttachment();
13460 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13462 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
13464 BeginCommandBuffer();
13465 // Bind pipeline to cmd buffer
13466 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13467 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13468 &descriptor_set, 0, nullptr);
13470 EndCommandBuffer();
13471 // Submit cmd buffer then destroy sampler
13472 VkSubmitInfo submit_info = {};
13473 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13474 submit_info.commandBufferCount = 1;
13475 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13476 // Submit cmd buffer and then destroy imageView while in-flight
13477 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13479 vkDestroyImageView(m_device->device(), view, nullptr);
13480 m_errorMonitor->VerifyFound();
13481 vkQueueWaitIdle(m_device->m_queue);
13482 // Now we can actually destroy imageView
13483 vkDestroyImageView(m_device->device(), view, NULL);
13484 vkDestroySampler(m_device->device(), sampler, nullptr);
13485 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13486 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13487 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13490 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
13491 TEST_DESCRIPTION("Delete in-use bufferView.");
13493 ASSERT_NO_FATAL_FAILURE(InitState());
13494 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13496 VkDescriptorPoolSize ds_type_count;
13497 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13498 ds_type_count.descriptorCount = 1;
13500 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13501 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13502 ds_pool_ci.maxSets = 1;
13503 ds_pool_ci.poolSizeCount = 1;
13504 ds_pool_ci.pPoolSizes = &ds_type_count;
13506 VkDescriptorPool ds_pool;
13507 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13508 ASSERT_VK_SUCCESS(err);
13510 VkDescriptorSetLayoutBinding layout_binding;
13511 layout_binding.binding = 0;
13512 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13513 layout_binding.descriptorCount = 1;
13514 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13515 layout_binding.pImmutableSamplers = NULL;
13517 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13518 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13519 ds_layout_ci.bindingCount = 1;
13520 ds_layout_ci.pBindings = &layout_binding;
13521 VkDescriptorSetLayout ds_layout;
13522 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13523 ASSERT_VK_SUCCESS(err);
13525 VkDescriptorSetAllocateInfo alloc_info = {};
13526 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13527 alloc_info.descriptorSetCount = 1;
13528 alloc_info.descriptorPool = ds_pool;
13529 alloc_info.pSetLayouts = &ds_layout;
13530 VkDescriptorSet descriptor_set;
13531 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13532 ASSERT_VK_SUCCESS(err);
13534 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13535 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13536 pipeline_layout_ci.pNext = NULL;
13537 pipeline_layout_ci.setLayoutCount = 1;
13538 pipeline_layout_ci.pSetLayouts = &ds_layout;
13540 VkPipelineLayout pipeline_layout;
13541 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13542 ASSERT_VK_SUCCESS(err);
13545 uint32_t queue_family_index = 0;
13546 VkBufferCreateInfo buffer_create_info = {};
13547 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
13548 buffer_create_info.size = 1024;
13549 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
13550 buffer_create_info.queueFamilyIndexCount = 1;
13551 buffer_create_info.pQueueFamilyIndices = &queue_family_index;
13553 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
13554 ASSERT_VK_SUCCESS(err);
13556 VkMemoryRequirements memory_reqs;
13557 VkDeviceMemory buffer_memory;
13559 VkMemoryAllocateInfo memory_info = {};
13560 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
13561 memory_info.allocationSize = 0;
13562 memory_info.memoryTypeIndex = 0;
13564 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
13565 memory_info.allocationSize = memory_reqs.size;
13566 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
13569 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
13570 ASSERT_VK_SUCCESS(err);
13571 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
13572 ASSERT_VK_SUCCESS(err);
13575 VkBufferViewCreateInfo bvci = {};
13576 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
13577 bvci.buffer = buffer;
13578 bvci.format = VK_FORMAT_R8_UNORM;
13579 bvci.range = VK_WHOLE_SIZE;
13581 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
13582 ASSERT_VK_SUCCESS(err);
13584 VkWriteDescriptorSet descriptor_write = {};
13585 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13586 descriptor_write.dstSet = descriptor_set;
13587 descriptor_write.dstBinding = 0;
13588 descriptor_write.descriptorCount = 1;
13589 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
13590 descriptor_write.pTexelBufferView = &view;
13592 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13594 char const *vsSource = "#version 450\n"
13596 "out gl_PerVertex { \n"
13597 " vec4 gl_Position;\n"
13600 " gl_Position = vec4(1);\n"
13602 char const *fsSource = "#version 450\n"
13604 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
13605 "layout(location=0) out vec4 x;\n"
13607 " x = imageLoad(s, 0);\n"
13609 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13610 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13611 VkPipelineObj pipe(m_device);
13612 pipe.AddShader(&vs);
13613 pipe.AddShader(&fs);
13614 pipe.AddColorAttachment();
13615 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13617 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
13619 BeginCommandBuffer();
13620 VkViewport viewport = {0, 0, 16, 16, 0, 1};
13621 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
13622 VkRect2D scissor = {{0, 0}, {16, 16}};
13623 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
13624 // Bind pipeline to cmd buffer
13625 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13626 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13627 &descriptor_set, 0, nullptr);
13629 EndCommandBuffer();
13631 VkSubmitInfo submit_info = {};
13632 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13633 submit_info.commandBufferCount = 1;
13634 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13635 // Submit cmd buffer and then destroy bufferView while in-flight
13636 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13638 vkDestroyBufferView(m_device->device(), view, nullptr);
13639 m_errorMonitor->VerifyFound();
13640 vkQueueWaitIdle(m_device->m_queue);
13641 // Now we can actually destroy bufferView
13642 vkDestroyBufferView(m_device->device(), view, NULL);
13643 vkDestroyBuffer(m_device->device(), buffer, NULL);
13644 vkFreeMemory(m_device->device(), buffer_memory, NULL);
13645 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13646 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13647 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13650 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
13651 TEST_DESCRIPTION("Delete in-use sampler.");
13653 ASSERT_NO_FATAL_FAILURE(InitState());
13654 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13656 VkDescriptorPoolSize ds_type_count;
13657 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13658 ds_type_count.descriptorCount = 1;
13660 VkDescriptorPoolCreateInfo ds_pool_ci = {};
13661 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13662 ds_pool_ci.maxSets = 1;
13663 ds_pool_ci.poolSizeCount = 1;
13664 ds_pool_ci.pPoolSizes = &ds_type_count;
13666 VkDescriptorPool ds_pool;
13667 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
13668 ASSERT_VK_SUCCESS(err);
13670 VkSamplerCreateInfo sampler_ci = {};
13671 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
13672 sampler_ci.pNext = NULL;
13673 sampler_ci.magFilter = VK_FILTER_NEAREST;
13674 sampler_ci.minFilter = VK_FILTER_NEAREST;
13675 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
13676 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13677 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13678 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
13679 sampler_ci.mipLodBias = 1.0;
13680 sampler_ci.anisotropyEnable = VK_FALSE;
13681 sampler_ci.maxAnisotropy = 1;
13682 sampler_ci.compareEnable = VK_FALSE;
13683 sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
13684 sampler_ci.minLod = 1.0;
13685 sampler_ci.maxLod = 1.0;
13686 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
13687 sampler_ci.unnormalizedCoordinates = VK_FALSE;
13690 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
13691 ASSERT_VK_SUCCESS(err);
13693 VkDescriptorSetLayoutBinding layout_binding;
13694 layout_binding.binding = 0;
13695 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13696 layout_binding.descriptorCount = 1;
13697 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
13698 layout_binding.pImmutableSamplers = NULL;
13700 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13701 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13702 ds_layout_ci.bindingCount = 1;
13703 ds_layout_ci.pBindings = &layout_binding;
13704 VkDescriptorSetLayout ds_layout;
13705 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
13706 ASSERT_VK_SUCCESS(err);
13708 VkDescriptorSetAllocateInfo alloc_info = {};
13709 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
13710 alloc_info.descriptorSetCount = 1;
13711 alloc_info.descriptorPool = ds_pool;
13712 alloc_info.pSetLayouts = &ds_layout;
13713 VkDescriptorSet descriptor_set;
13714 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
13715 ASSERT_VK_SUCCESS(err);
13717 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13718 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13719 pipeline_layout_ci.pNext = NULL;
13720 pipeline_layout_ci.setLayoutCount = 1;
13721 pipeline_layout_ci.pSetLayouts = &ds_layout;
13723 VkPipelineLayout pipeline_layout;
13724 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13725 ASSERT_VK_SUCCESS(err);
13727 VkImageObj image(m_device);
13728 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13729 ASSERT_TRUE(image.initialized());
13732 VkImageViewCreateInfo ivci = {};
13733 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
13734 ivci.image = image.handle();
13735 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
13736 ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
13737 ivci.subresourceRange.layerCount = 1;
13738 ivci.subresourceRange.baseMipLevel = 0;
13739 ivci.subresourceRange.levelCount = 1;
13740 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
13742 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
13743 ASSERT_VK_SUCCESS(err);
13745 VkDescriptorImageInfo image_info{};
13746 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
13747 image_info.imageView = view;
13748 image_info.sampler = sampler;
13750 VkWriteDescriptorSet descriptor_write = {};
13751 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
13752 descriptor_write.dstSet = descriptor_set;
13753 descriptor_write.dstBinding = 0;
13754 descriptor_write.descriptorCount = 1;
13755 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
13756 descriptor_write.pImageInfo = &image_info;
13758 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
13760 // Create PSO to use the sampler
13761 char const *vsSource = "#version 450\n"
13763 "out gl_PerVertex { \n"
13764 " vec4 gl_Position;\n"
13767 " gl_Position = vec4(1);\n"
13769 char const *fsSource = "#version 450\n"
13771 "layout(set=0, binding=0) uniform sampler2D s;\n"
13772 "layout(location=0) out vec4 x;\n"
13774 " x = texture(s, vec2(1));\n"
13776 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
13777 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13778 VkPipelineObj pipe(m_device);
13779 pipe.AddShader(&vs);
13780 pipe.AddShader(&fs);
13781 pipe.AddColorAttachment();
13782 pipe.CreateVKPipeline(pipeline_layout, renderPass());
13784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x");
13786 BeginCommandBuffer();
13787 // Bind pipeline to cmd buffer
13788 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
13789 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
13790 &descriptor_set, 0, nullptr);
13792 EndCommandBuffer();
13793 // Submit cmd buffer then destroy sampler
13794 VkSubmitInfo submit_info = {};
13795 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13796 submit_info.commandBufferCount = 1;
13797 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13798 // Submit cmd buffer and then destroy sampler while in-flight
13799 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13801 vkDestroySampler(m_device->device(), sampler, nullptr);
13802 m_errorMonitor->VerifyFound();
13803 vkQueueWaitIdle(m_device->m_queue);
13804 // Now we can actually destroy sampler
13805 vkDestroySampler(m_device->device(), sampler, nullptr);
13806 vkDestroyImageView(m_device->device(), view, NULL);
13807 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13808 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13809 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13812 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
13813 TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already "
13814 "signaled but not waited on by the queue. Wait on a "
13815 "fence that has not yet been submitted to a queue.");
13817 ASSERT_NO_FATAL_FAILURE(InitState());
13818 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13820 const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
13821 const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during "
13822 "acquire next image.";
13824 BeginCommandBuffer();
13825 EndCommandBuffer();
13827 VkSemaphoreCreateInfo semaphore_create_info = {};
13828 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
13829 VkSemaphore semaphore;
13830 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
13831 VkSubmitInfo submit_info = {};
13832 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
13833 submit_info.commandBufferCount = 1;
13834 submit_info.pCommandBuffers = &m_commandBuffer->handle();
13835 submit_info.signalSemaphoreCount = 1;
13836 submit_info.pSignalSemaphores = &semaphore;
13837 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13838 m_errorMonitor->SetDesiredFailureMsg(0, "");
13839 vkResetCommandBuffer(m_commandBuffer->handle(), 0);
13840 BeginCommandBuffer();
13841 EndCommandBuffer();
13842 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
13843 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13844 m_errorMonitor->VerifyFound();
13846 VkFenceCreateInfo fence_create_info = {};
13847 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
13849 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
13851 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
13852 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
13853 m_errorMonitor->VerifyFound();
13855 vkDeviceWaitIdle(m_device->device());
13856 vkDestroyFence(m_device->device(), fence, nullptr);
13857 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
13860 TEST_F(VkLayerTest, FramebufferIncompatible) {
13861 TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
13862 "that does not match the framebuffer for the active "
13864 ASSERT_NO_FATAL_FAILURE(InitState());
13865 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13867 // A renderpass with one color attachment.
13868 VkAttachmentDescription attachment = {0,
13869 VK_FORMAT_B8G8R8A8_UNORM,
13870 VK_SAMPLE_COUNT_1_BIT,
13871 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13872 VK_ATTACHMENT_STORE_OP_STORE,
13873 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13874 VK_ATTACHMENT_STORE_OP_DONT_CARE,
13875 VK_IMAGE_LAYOUT_UNDEFINED,
13876 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13878 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
13880 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
13882 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
13885 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
13886 ASSERT_VK_SUCCESS(err);
13888 // A compatible framebuffer.
13889 VkImageObj image(m_device);
13890 image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
13891 ASSERT_TRUE(image.initialized());
13893 VkImageViewCreateInfo ivci = {
13894 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
13898 VK_IMAGE_VIEW_TYPE_2D,
13899 VK_FORMAT_B8G8R8A8_UNORM,
13900 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13901 VK_COMPONENT_SWIZZLE_IDENTITY},
13902 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
13905 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
13906 ASSERT_VK_SUCCESS(err);
13908 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
13910 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
13911 ASSERT_VK_SUCCESS(err);
13913 VkCommandBufferAllocateInfo cbai = {};
13914 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
13915 cbai.commandPool = m_commandPool;
13916 cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
13917 cbai.commandBufferCount = 1;
13919 VkCommandBuffer sec_cb;
13920 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
13921 ASSERT_VK_SUCCESS(err);
13922 VkCommandBufferBeginInfo cbbi = {};
13923 VkCommandBufferInheritanceInfo cbii = {};
13924 cbii.renderPass = renderPass();
13925 cbii.framebuffer = fb;
13926 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
13928 cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
13929 cbbi.pInheritanceInfo = &cbii;
13930 vkBeginCommandBuffer(sec_cb, &cbbi);
13931 vkEndCommandBuffer(sec_cb);
13933 VkCommandBufferBeginInfo cbbi2 = {
13934 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
13937 vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
13938 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
13940 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13941 " that is not the same as the primaryCB's current active framebuffer ");
13942 vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
13943 m_errorMonitor->VerifyFound();
13945 vkDestroyImageView(m_device->device(), view, NULL);
13946 vkDestroyRenderPass(m_device->device(), rp, NULL);
13947 vkDestroyFramebuffer(m_device->device(), fb, NULL);
13950 TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
13951 TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
13952 "invalid value. If logicOp is not available, attempt to "
13953 "use it and verify that we see the correct error.");
13954 ASSERT_NO_FATAL_FAILURE(InitState());
13955 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13957 auto features = m_device->phy().features();
13958 // Set the expected error depending on whether or not logicOp available
13959 if (VK_FALSE == features.logicOp) {
13960 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not "
13961 "enabled, logicOpEnable must be "
13964 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
13966 // Create a pipeline using logicOp
13969 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13970 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13972 VkPipelineLayout pipeline_layout;
13973 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
13974 ASSERT_VK_SUCCESS(err);
13976 VkPipelineViewportStateCreateInfo vp_state_ci = {};
13977 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13978 vp_state_ci.viewportCount = 1;
13979 VkViewport vp = {}; // Just need dummy vp to point to
13980 vp_state_ci.pViewports = &vp;
13981 vp_state_ci.scissorCount = 1;
13982 VkRect2D scissors = {}; // Dummy scissors to point to
13983 vp_state_ci.pScissors = &scissors;
13985 VkPipelineShaderStageCreateInfo shaderStages[2];
13986 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
13988 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13989 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13990 shaderStages[0] = vs.GetStageCreateInfo();
13991 shaderStages[1] = fs.GetStageCreateInfo();
13993 VkPipelineVertexInputStateCreateInfo vi_ci = {};
13994 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13996 VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
13997 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13998 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
14000 VkPipelineRasterizationStateCreateInfo rs_ci = {};
14001 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14002 rs_ci.lineWidth = 1.0f;
14004 VkPipelineColorBlendAttachmentState att = {};
14005 att.blendEnable = VK_FALSE;
14006 att.colorWriteMask = 0xf;
14008 VkPipelineColorBlendStateCreateInfo cb_ci = {};
14009 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
14010 // Enable logicOp & set logicOp to value 1 beyond allowed entries
14011 cb_ci.logicOpEnable = VK_TRUE;
14012 cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
14013 cb_ci.attachmentCount = 1;
14014 cb_ci.pAttachments = &att;
14016 VkPipelineMultisampleStateCreateInfo ms_ci = {};
14017 ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14018 ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14020 VkGraphicsPipelineCreateInfo gp_ci = {};
14021 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14022 gp_ci.stageCount = 2;
14023 gp_ci.pStages = shaderStages;
14024 gp_ci.pVertexInputState = &vi_ci;
14025 gp_ci.pInputAssemblyState = &ia_ci;
14026 gp_ci.pViewportState = &vp_state_ci;
14027 gp_ci.pRasterizationState = &rs_ci;
14028 gp_ci.pColorBlendState = &cb_ci;
14029 gp_ci.pMultisampleState = &ms_ci;
14030 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14031 gp_ci.layout = pipeline_layout;
14032 gp_ci.renderPass = renderPass();
14034 VkPipelineCacheCreateInfo pc_ci = {};
14035 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14037 VkPipeline pipeline;
14038 VkPipelineCache pipelineCache;
14039 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
14040 ASSERT_VK_SUCCESS(err);
14042 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
14043 m_errorMonitor->VerifyFound();
14044 if (VK_SUCCESS == err) {
14045 vkDestroyPipeline(m_device->device(), pipeline, NULL);
14047 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
14048 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
14050 #endif // DRAW_STATE_TESTS
14052 #if THREADING_TESTS
14053 #if GTEST_IS_THREADSAFE
14054 struct thread_data_struct {
14055 VkCommandBuffer commandBuffer;
14060 extern "C" void *AddToCommandBuffer(void *arg) {
14061 struct thread_data_struct *data = (struct thread_data_struct *)arg;
14063 for (int i = 0; i < 80000; i++) {
14064 vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
14065 if (data->bailout) {
14072 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
14073 test_platform_thread thread;
14075 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
14077 ASSERT_NO_FATAL_FAILURE(InitState());
14078 ASSERT_NO_FATAL_FAILURE(InitViewport());
14079 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14081 // Calls AllocateCommandBuffers
14082 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
14084 // Avoid creating RenderPass
14085 commandBuffer.BeginCommandBuffer();
14087 VkEventCreateInfo event_info;
14091 memset(&event_info, 0, sizeof(event_info));
14092 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
14094 err = vkCreateEvent(device(), &event_info, NULL, &event);
14095 ASSERT_VK_SUCCESS(err);
14097 err = vkResetEvent(device(), event);
14098 ASSERT_VK_SUCCESS(err);
14100 struct thread_data_struct data;
14101 data.commandBuffer = commandBuffer.GetBufferHandle();
14102 data.event = event;
14103 data.bailout = false;
14104 m_errorMonitor->SetBailout(&data.bailout);
14106 // First do some correct operations using multiple threads.
14107 // Add many entries to command buffer from another thread.
14108 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14109 // Make non-conflicting calls from this thread at the same time.
14110 for (int i = 0; i < 80000; i++) {
14112 vkEnumeratePhysicalDevices(instance(), &count, NULL);
14114 test_platform_thread_join(thread, NULL);
14116 // Then do some incorrect operations using multiple threads.
14117 // Add many entries to command buffer from another thread.
14118 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
14119 // Add many entries to command buffer from this thread at the same time.
14120 AddToCommandBuffer(&data);
14122 test_platform_thread_join(thread, NULL);
14123 commandBuffer.EndCommandBuffer();
14125 m_errorMonitor->SetBailout(NULL);
14127 m_errorMonitor->VerifyFound();
14129 vkDestroyEvent(device(), event, NULL);
14131 #endif // GTEST_IS_THREADSAFE
14132 #endif // THREADING_TESTS
14134 #if SHADER_CHECKER_TESTS
14135 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
14136 TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14137 "with an impossible code size");
14139 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
14141 ASSERT_NO_FATAL_FAILURE(InitState());
14142 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14144 VkShaderModule module;
14145 VkShaderModuleCreateInfo moduleCreateInfo;
14146 struct icd_spv_header spv;
14148 spv.magic = ICD_SPV_MAGIC;
14149 spv.version = ICD_SPV_VERSION;
14152 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14153 moduleCreateInfo.pNext = NULL;
14154 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14155 moduleCreateInfo.codeSize = 4;
14156 moduleCreateInfo.flags = 0;
14157 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14159 m_errorMonitor->VerifyFound();
14162 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
14163 TEST_DESCRIPTION("Test that an error is produced for a spirv module "
14164 "with a bad magic number");
14166 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
14168 ASSERT_NO_FATAL_FAILURE(InitState());
14169 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14171 VkShaderModule module;
14172 VkShaderModuleCreateInfo moduleCreateInfo;
14173 struct icd_spv_header spv;
14175 spv.magic = ~ICD_SPV_MAGIC;
14176 spv.version = ICD_SPV_VERSION;
14179 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14180 moduleCreateInfo.pNext = NULL;
14181 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14182 moduleCreateInfo.codeSize = sizeof(spv) + 10;
14183 moduleCreateInfo.flags = 0;
14184 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14186 m_errorMonitor->VerifyFound();
14190 // Not currently covered by SPIRV-Tools validator
14191 TEST_F(VkLayerTest, InvalidSPIRVVersion) {
14192 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14193 "Invalid SPIR-V header");
14195 ASSERT_NO_FATAL_FAILURE(InitState());
14196 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14198 VkShaderModule module;
14199 VkShaderModuleCreateInfo moduleCreateInfo;
14200 struct icd_spv_header spv;
14202 spv.magic = ICD_SPV_MAGIC;
14203 spv.version = ~ICD_SPV_VERSION;
14206 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
14207 moduleCreateInfo.pNext = NULL;
14209 moduleCreateInfo.pCode = (const uint32_t *)&spv;
14210 moduleCreateInfo.codeSize = sizeof(spv) + 10;
14211 moduleCreateInfo.flags = 0;
14212 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
14214 m_errorMonitor->VerifyFound();
14218 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
14219 TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
14220 "is not consumed by the fragment stage");
14221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
14223 ASSERT_NO_FATAL_FAILURE(InitState());
14224 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14226 char const *vsSource = "#version 450\n"
14228 "layout(location=0) out float x;\n"
14229 "out gl_PerVertex {\n"
14230 " vec4 gl_Position;\n"
14233 " gl_Position = vec4(1);\n"
14236 char const *fsSource = "#version 450\n"
14238 "layout(location=0) out vec4 color;\n"
14240 " color = vec4(1);\n"
14243 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14244 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14246 VkPipelineObj pipe(m_device);
14247 pipe.AddColorAttachment();
14248 pipe.AddShader(&vs);
14249 pipe.AddShader(&fs);
14251 VkDescriptorSetObj descriptorSet(m_device);
14252 descriptorSet.AppendDummy();
14253 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14255 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14257 m_errorMonitor->VerifyFound();
14260 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
14261 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14262 "which is not present in the outputs of the previous stage");
14264 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14266 ASSERT_NO_FATAL_FAILURE(InitState());
14267 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14269 char const *vsSource = "#version 450\n"
14271 "out gl_PerVertex {\n"
14272 " vec4 gl_Position;\n"
14275 " gl_Position = vec4(1);\n"
14277 char const *fsSource = "#version 450\n"
14279 "layout(location=0) in float x;\n"
14280 "layout(location=0) out vec4 color;\n"
14282 " color = vec4(x);\n"
14285 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14286 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14288 VkPipelineObj pipe(m_device);
14289 pipe.AddColorAttachment();
14290 pipe.AddShader(&vs);
14291 pipe.AddShader(&fs);
14293 VkDescriptorSetObj descriptorSet(m_device);
14294 descriptorSet.AppendDummy();
14295 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14297 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14299 m_errorMonitor->VerifyFound();
14302 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
14303 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
14304 "within an interace block, which is not present in the outputs "
14305 "of the previous stage.");
14306 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
14308 ASSERT_NO_FATAL_FAILURE(InitState());
14309 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14311 char const *vsSource = "#version 450\n"
14313 "out gl_PerVertex {\n"
14314 " vec4 gl_Position;\n"
14317 " gl_Position = vec4(1);\n"
14319 char const *fsSource = "#version 450\n"
14321 "in block { layout(location=0) float x; } ins;\n"
14322 "layout(location=0) out vec4 color;\n"
14324 " color = vec4(ins.x);\n"
14327 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14328 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14330 VkPipelineObj pipe(m_device);
14331 pipe.AddColorAttachment();
14332 pipe.AddShader(&vs);
14333 pipe.AddShader(&fs);
14335 VkDescriptorSetObj descriptorSet(m_device);
14336 descriptorSet.AppendDummy();
14337 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14339 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14341 m_errorMonitor->VerifyFound();
14344 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
14345 TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
14346 "across the VS->FS interface");
14347 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
14348 "output arr[2] of float32' vs 'ptr to "
14349 "input arr[3] of float32'");
14351 ASSERT_NO_FATAL_FAILURE(InitState());
14352 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14354 char const *vsSource = "#version 450\n"
14356 "layout(location=0) out float x[2];\n"
14357 "out gl_PerVertex {\n"
14358 " vec4 gl_Position;\n"
14361 " x[0] = 0; x[1] = 0;\n"
14362 " gl_Position = vec4(1);\n"
14364 char const *fsSource = "#version 450\n"
14366 "layout(location=0) in float x[3];\n"
14367 "layout(location=0) out vec4 color;\n"
14369 " color = vec4(x[0] + x[1] + x[2]);\n"
14372 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14373 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14375 VkPipelineObj pipe(m_device);
14376 pipe.AddColorAttachment();
14377 pipe.AddShader(&vs);
14378 pipe.AddShader(&fs);
14380 VkDescriptorSetObj descriptorSet(m_device);
14381 descriptorSet.AppendDummy();
14382 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14384 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14386 m_errorMonitor->VerifyFound();
14389 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
14390 TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14391 "the VS->FS interface");
14392 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14394 ASSERT_NO_FATAL_FAILURE(InitState());
14395 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14397 char const *vsSource = "#version 450\n"
14399 "layout(location=0) out int x;\n"
14400 "out gl_PerVertex {\n"
14401 " vec4 gl_Position;\n"
14405 " gl_Position = vec4(1);\n"
14407 char const *fsSource = "#version 450\n"
14409 "layout(location=0) in float x;\n" /* VS writes int */
14410 "layout(location=0) out vec4 color;\n"
14412 " color = vec4(x);\n"
14415 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14416 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14418 VkPipelineObj pipe(m_device);
14419 pipe.AddColorAttachment();
14420 pipe.AddShader(&vs);
14421 pipe.AddShader(&fs);
14423 VkDescriptorSetObj descriptorSet(m_device);
14424 descriptorSet.AppendDummy();
14425 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14427 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14429 m_errorMonitor->VerifyFound();
14432 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
14433 TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
14434 "the VS->FS interface, when the variable is contained within "
14435 "an interface block");
14436 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
14438 ASSERT_NO_FATAL_FAILURE(InitState());
14439 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14441 char const *vsSource = "#version 450\n"
14443 "out block { layout(location=0) int x; } outs;\n"
14444 "out gl_PerVertex {\n"
14445 " vec4 gl_Position;\n"
14449 " gl_Position = vec4(1);\n"
14451 char const *fsSource = "#version 450\n"
14453 "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
14454 "layout(location=0) out vec4 color;\n"
14456 " color = vec4(ins.x);\n"
14459 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14460 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14462 VkPipelineObj pipe(m_device);
14463 pipe.AddColorAttachment();
14464 pipe.AddShader(&vs);
14465 pipe.AddShader(&fs);
14467 VkDescriptorSetObj descriptorSet(m_device);
14468 descriptorSet.AppendDummy();
14469 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14471 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14473 m_errorMonitor->VerifyFound();
14476 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
14477 TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
14478 "the VS->FS interface; This should manifest as a not-written/not-consumed "
14479 "pair, but flushes out broken walking of the interfaces");
14480 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
14482 ASSERT_NO_FATAL_FAILURE(InitState());
14483 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14485 char const *vsSource = "#version 450\n"
14487 "out block { layout(location=1) float x; } outs;\n"
14488 "out gl_PerVertex {\n"
14489 " vec4 gl_Position;\n"
14493 " gl_Position = vec4(1);\n"
14495 char const *fsSource = "#version 450\n"
14497 "in block { layout(location=0) float x; } ins;\n"
14498 "layout(location=0) out vec4 color;\n"
14500 " color = vec4(ins.x);\n"
14503 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14504 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14506 VkPipelineObj pipe(m_device);
14507 pipe.AddColorAttachment();
14508 pipe.AddShader(&vs);
14509 pipe.AddShader(&fs);
14511 VkDescriptorSetObj descriptorSet(m_device);
14512 descriptorSet.AppendDummy();
14513 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14515 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14517 m_errorMonitor->VerifyFound();
14520 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
14521 TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
14522 "VS->FS interface. It's not enough to have the same set of locations in "
14523 "use; matching is defined in terms of spirv variables.");
14524 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
14526 ASSERT_NO_FATAL_FAILURE(InitState());
14527 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14529 char const *vsSource = "#version 450\n"
14531 "out block { layout(location=0, component=0) float x; } outs;\n"
14532 "out gl_PerVertex {\n"
14533 " vec4 gl_Position;\n"
14537 " gl_Position = vec4(1);\n"
14539 char const *fsSource = "#version 450\n"
14541 "in block { layout(location=0, component=1) float x; } ins;\n"
14542 "layout(location=0) out vec4 color;\n"
14544 " color = vec4(ins.x);\n"
14547 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14548 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14550 VkPipelineObj pipe(m_device);
14551 pipe.AddColorAttachment();
14552 pipe.AddShader(&vs);
14553 pipe.AddShader(&fs);
14555 VkDescriptorSetObj descriptorSet(m_device);
14556 descriptorSet.AppendDummy();
14557 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14559 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14561 m_errorMonitor->VerifyFound();
14564 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
14565 TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
14566 "not consumed by the vertex shader");
14567 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14569 ASSERT_NO_FATAL_FAILURE(InitState());
14570 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14572 VkVertexInputBindingDescription input_binding;
14573 memset(&input_binding, 0, sizeof(input_binding));
14575 VkVertexInputAttributeDescription input_attrib;
14576 memset(&input_attrib, 0, sizeof(input_attrib));
14577 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14579 char const *vsSource = "#version 450\n"
14581 "out gl_PerVertex {\n"
14582 " vec4 gl_Position;\n"
14585 " gl_Position = vec4(1);\n"
14587 char const *fsSource = "#version 450\n"
14589 "layout(location=0) out vec4 color;\n"
14591 " color = vec4(1);\n"
14594 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14595 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14597 VkPipelineObj pipe(m_device);
14598 pipe.AddColorAttachment();
14599 pipe.AddShader(&vs);
14600 pipe.AddShader(&fs);
14602 pipe.AddVertexInputBindings(&input_binding, 1);
14603 pipe.AddVertexInputAttribs(&input_attrib, 1);
14605 VkDescriptorSetObj descriptorSet(m_device);
14606 descriptorSet.AppendDummy();
14607 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14609 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14611 m_errorMonitor->VerifyFound();
14614 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
14615 TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
14616 "vertex attributes. This flushes out bad behavior in the interface walker");
14617 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
14619 ASSERT_NO_FATAL_FAILURE(InitState());
14620 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14622 VkVertexInputBindingDescription input_binding;
14623 memset(&input_binding, 0, sizeof(input_binding));
14625 VkVertexInputAttributeDescription input_attrib;
14626 memset(&input_attrib, 0, sizeof(input_attrib));
14627 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14629 char const *vsSource = "#version 450\n"
14631 "layout(location=1) in float x;\n"
14632 "out gl_PerVertex {\n"
14633 " vec4 gl_Position;\n"
14636 " gl_Position = vec4(x);\n"
14638 char const *fsSource = "#version 450\n"
14640 "layout(location=0) out vec4 color;\n"
14642 " color = vec4(1);\n"
14645 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14646 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14648 VkPipelineObj pipe(m_device);
14649 pipe.AddColorAttachment();
14650 pipe.AddShader(&vs);
14651 pipe.AddShader(&fs);
14653 pipe.AddVertexInputBindings(&input_binding, 1);
14654 pipe.AddVertexInputAttribs(&input_attrib, 1);
14656 VkDescriptorSetObj descriptorSet(m_device);
14657 descriptorSet.AppendDummy();
14658 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14660 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14662 m_errorMonitor->VerifyFound();
14665 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
14666 TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
14667 "provided by a vertex attribute");
14668 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
14670 ASSERT_NO_FATAL_FAILURE(InitState());
14671 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14673 char const *vsSource = "#version 450\n"
14675 "layout(location=0) in vec4 x;\n" /* not provided */
14676 "out gl_PerVertex {\n"
14677 " vec4 gl_Position;\n"
14680 " gl_Position = x;\n"
14682 char const *fsSource = "#version 450\n"
14684 "layout(location=0) out vec4 color;\n"
14686 " color = vec4(1);\n"
14689 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14690 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14692 VkPipelineObj pipe(m_device);
14693 pipe.AddColorAttachment();
14694 pipe.AddShader(&vs);
14695 pipe.AddShader(&fs);
14697 VkDescriptorSetObj descriptorSet(m_device);
14698 descriptorSet.AppendDummy();
14699 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14701 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14703 m_errorMonitor->VerifyFound();
14706 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
14707 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
14708 "fundamental type (float/int/uint) of an attribute and the "
14709 "vertex shader input that consumes it");
14710 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
14712 ASSERT_NO_FATAL_FAILURE(InitState());
14713 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14715 VkVertexInputBindingDescription input_binding;
14716 memset(&input_binding, 0, sizeof(input_binding));
14718 VkVertexInputAttributeDescription input_attrib;
14719 memset(&input_attrib, 0, sizeof(input_attrib));
14720 input_attrib.format = VK_FORMAT_R32_SFLOAT;
14722 char const *vsSource = "#version 450\n"
14724 "layout(location=0) in int x;\n" /* attrib provided float */
14725 "out gl_PerVertex {\n"
14726 " vec4 gl_Position;\n"
14729 " gl_Position = vec4(x);\n"
14731 char const *fsSource = "#version 450\n"
14733 "layout(location=0) out vec4 color;\n"
14735 " color = vec4(1);\n"
14738 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14739 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14741 VkPipelineObj pipe(m_device);
14742 pipe.AddColorAttachment();
14743 pipe.AddShader(&vs);
14744 pipe.AddShader(&fs);
14746 pipe.AddVertexInputBindings(&input_binding, 1);
14747 pipe.AddVertexInputAttribs(&input_attrib, 1);
14749 VkDescriptorSetObj descriptorSet(m_device);
14750 descriptorSet.AppendDummy();
14751 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14753 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14755 m_errorMonitor->VerifyFound();
14758 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
14759 TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
14760 "shaders for the same stage");
14761 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14762 "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
14764 ASSERT_NO_FATAL_FAILURE(InitState());
14765 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14767 char const *vsSource = "#version 450\n"
14769 "out gl_PerVertex {\n"
14770 " vec4 gl_Position;\n"
14773 " gl_Position = vec4(1);\n"
14775 char const *fsSource = "#version 450\n"
14777 "layout(location=0) out vec4 color;\n"
14779 " color = vec4(1);\n"
14782 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14783 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14785 VkPipelineObj pipe(m_device);
14786 pipe.AddColorAttachment();
14787 pipe.AddShader(&vs);
14788 pipe.AddShader(&vs);
14789 pipe.AddShader(&fs);
14791 VkDescriptorSetObj descriptorSet(m_device);
14792 descriptorSet.AppendDummy();
14793 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14795 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14797 m_errorMonitor->VerifyFound();
14800 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
14801 TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
14802 "as vertex attributes");
14803 m_errorMonitor->ExpectSuccess();
14805 ASSERT_NO_FATAL_FAILURE(InitState());
14806 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14808 VkVertexInputBindingDescription input_binding;
14809 memset(&input_binding, 0, sizeof(input_binding));
14811 VkVertexInputAttributeDescription input_attribs[2];
14812 memset(input_attribs, 0, sizeof(input_attribs));
14814 for (int i = 0; i < 2; i++) {
14815 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14816 input_attribs[i].location = i;
14819 char const *vsSource = "#version 450\n"
14821 "layout(location=0) in mat2x4 x;\n"
14822 "out gl_PerVertex {\n"
14823 " vec4 gl_Position;\n"
14826 " gl_Position = x[0] + x[1];\n"
14828 char const *fsSource = "#version 450\n"
14830 "layout(location=0) out vec4 color;\n"
14832 " color = vec4(1);\n"
14835 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14836 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14838 VkPipelineObj pipe(m_device);
14839 pipe.AddColorAttachment();
14840 pipe.AddShader(&vs);
14841 pipe.AddShader(&fs);
14843 pipe.AddVertexInputBindings(&input_binding, 1);
14844 pipe.AddVertexInputAttribs(input_attribs, 2);
14846 VkDescriptorSetObj descriptorSet(m_device);
14847 descriptorSet.AppendDummy();
14848 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14850 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14852 /* expect success */
14853 m_errorMonitor->VerifyNotFound();
14856 TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
14857 m_errorMonitor->ExpectSuccess();
14859 ASSERT_NO_FATAL_FAILURE(InitState());
14860 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14862 VkVertexInputBindingDescription input_binding;
14863 memset(&input_binding, 0, sizeof(input_binding));
14865 VkVertexInputAttributeDescription input_attribs[2];
14866 memset(input_attribs, 0, sizeof(input_attribs));
14868 for (int i = 0; i < 2; i++) {
14869 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14870 input_attribs[i].location = i;
14873 char const *vsSource = "#version 450\n"
14875 "layout(location=0) in vec4 x[2];\n"
14876 "out gl_PerVertex {\n"
14877 " vec4 gl_Position;\n"
14880 " gl_Position = x[0] + x[1];\n"
14882 char const *fsSource = "#version 450\n"
14884 "layout(location=0) out vec4 color;\n"
14886 " color = vec4(1);\n"
14889 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14890 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14892 VkPipelineObj pipe(m_device);
14893 pipe.AddColorAttachment();
14894 pipe.AddShader(&vs);
14895 pipe.AddShader(&fs);
14897 pipe.AddVertexInputBindings(&input_binding, 1);
14898 pipe.AddVertexInputAttribs(input_attribs, 2);
14900 VkDescriptorSetObj descriptorSet(m_device);
14901 descriptorSet.AppendDummy();
14902 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14904 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14906 m_errorMonitor->VerifyNotFound();
14909 TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
14910 TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
14911 "through multiple vertex shader inputs, each consuming a different "
14912 "subset of the components.");
14913 m_errorMonitor->ExpectSuccess();
14915 ASSERT_NO_FATAL_FAILURE(InitState());
14916 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14918 VkVertexInputBindingDescription input_binding;
14919 memset(&input_binding, 0, sizeof(input_binding));
14921 VkVertexInputAttributeDescription input_attribs[3];
14922 memset(input_attribs, 0, sizeof(input_attribs));
14924 for (int i = 0; i < 3; i++) {
14925 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
14926 input_attribs[i].location = i;
14929 char const *vsSource = "#version 450\n"
14931 "layout(location=0) in vec4 x;\n"
14932 "layout(location=1) in vec3 y1;\n"
14933 "layout(location=1, component=3) in float y2;\n"
14934 "layout(location=2) in vec4 z;\n"
14935 "out gl_PerVertex {\n"
14936 " vec4 gl_Position;\n"
14939 " gl_Position = x + vec4(y1, y2) + z;\n"
14941 char const *fsSource = "#version 450\n"
14943 "layout(location=0) out vec4 color;\n"
14945 " color = vec4(1);\n"
14948 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14949 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14951 VkPipelineObj pipe(m_device);
14952 pipe.AddColorAttachment();
14953 pipe.AddShader(&vs);
14954 pipe.AddShader(&fs);
14956 pipe.AddVertexInputBindings(&input_binding, 1);
14957 pipe.AddVertexInputAttribs(input_attribs, 3);
14959 VkDescriptorSetObj descriptorSet(m_device);
14960 descriptorSet.AppendDummy();
14961 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
14963 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
14965 m_errorMonitor->VerifyNotFound();
14968 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
14969 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14970 "No entrypoint found named `foo`");
14972 ASSERT_NO_FATAL_FAILURE(InitState());
14973 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14975 char const *vsSource = "#version 450\n"
14976 "out gl_PerVertex {\n"
14977 " vec4 gl_Position;\n"
14980 " gl_Position = vec4(0);\n"
14982 char const *fsSource = "#version 450\n"
14984 "layout(location=0) out vec4 color;\n"
14986 " color = vec4(1);\n"
14989 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
14990 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
14992 VkPipelineObj pipe(m_device);
14993 pipe.AddColorAttachment();
14994 pipe.AddShader(&vs);
14995 pipe.AddShader(&fs);
14997 VkDescriptorSetObj descriptorSet(m_device);
14998 descriptorSet.AppendDummy();
14999 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15001 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15003 m_errorMonitor->VerifyFound();
15006 TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
15007 m_errorMonitor->ExpectSuccess();
15009 ASSERT_NO_FATAL_FAILURE(InitState());
15010 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15012 char const *vsSource = "#version 450\n"
15013 "out gl_PerVertex {\n"
15014 " vec4 gl_Position;\n"
15017 " gl_Position = vec4(0);\n"
15019 char const *fsSource = "#version 450\n"
15021 "layout(location=0) out vec4 color;\n"
15023 " color = vec4(1);\n"
15026 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15027 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15029 VkPipelineObj pipe(m_device);
15030 pipe.AddColorAttachment();
15031 pipe.AddShader(&vs);
15032 pipe.AddShader(&fs);
15034 VkDescriptorSetObj descriptorSet(m_device);
15035 descriptorSet.AppendDummy();
15036 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15038 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15040 m_errorMonitor->VerifyNotFound();
15043 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
15044 m_errorMonitor->SetDesiredFailureMsg(
15045 VK_DEBUG_REPORT_ERROR_BIT_EXT,
15046 "pDepthStencilState is NULL when rasterization is enabled and subpass "
15047 "uses a depth/stencil attachment");
15049 ASSERT_NO_FATAL_FAILURE(InitState());
15050 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15052 char const *vsSource = "#version 450\n"
15053 "void main(){ gl_Position = vec4(0); }\n";
15054 char const *fsSource = "#version 450\n"
15056 "layout(location=0) out vec4 color;\n"
15058 " color = vec4(1);\n"
15061 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15062 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15064 VkPipelineObj pipe(m_device);
15065 pipe.AddColorAttachment();
15066 pipe.AddShader(&vs);
15067 pipe.AddShader(&fs);
15069 VkDescriptorSetObj descriptorSet(m_device);
15070 descriptorSet.AppendDummy();
15071 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15073 VkAttachmentDescription attachments[] = {
15074 { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
15075 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15076 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15077 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15079 { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT,
15080 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15081 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
15082 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
15085 VkAttachmentReference refs[] = {
15086 { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
15087 { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL },
15089 VkSubpassDescription subpass = {
15090 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
15091 1, &refs[0], nullptr, &refs[1],
15094 VkRenderPassCreateInfo rpci = {
15095 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
15096 0, 2, attachments, 1, &subpass, 0, nullptr
15099 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15100 ASSERT_VK_SUCCESS(err);
15102 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
15104 m_errorMonitor->VerifyFound();
15106 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15109 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
15110 TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
15111 "set out in 14.1.3: fundamental type must match, and producer side must "
15112 "have at least as many components");
15113 m_errorMonitor->ExpectSuccess();
15115 // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
15117 ASSERT_NO_FATAL_FAILURE(InitState());
15118 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15120 char const *vsSource = "#version 450\n"
15121 "out gl_PerVertex {\n"
15122 " vec4 gl_Position;\n"
15124 "layout(location=0) out vec3 x;\n"
15125 "layout(location=1) out ivec3 y;\n"
15126 "layout(location=2) out vec3 z;\n"
15128 " gl_Position = vec4(0);\n"
15129 " x = vec3(0); y = ivec3(0); z = vec3(0);\n"
15131 char const *fsSource = "#version 450\n"
15133 "layout(location=0) out vec4 color;\n"
15134 "layout(location=0) in float x;\n"
15135 "layout(location=1) flat in int y;\n"
15136 "layout(location=2) in vec2 z;\n"
15138 " color = vec4(1 + x + y + z.x);\n"
15141 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15142 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15144 VkPipelineObj pipe(m_device);
15145 pipe.AddColorAttachment();
15146 pipe.AddShader(&vs);
15147 pipe.AddShader(&fs);
15149 VkDescriptorSetObj descriptorSet(m_device);
15150 descriptorSet.AppendDummy();
15151 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15153 VkResult err = VK_SUCCESS;
15154 err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15155 ASSERT_VK_SUCCESS(err);
15157 m_errorMonitor->VerifyNotFound();
15160 TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
15161 TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
15162 "passed between the TCS and TES stages");
15163 m_errorMonitor->ExpectSuccess();
15165 ASSERT_NO_FATAL_FAILURE(InitState());
15166 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15168 if (!m_device->phy().features().tessellationShader) {
15169 printf("Device does not support tessellation shaders; skipped.\n");
15173 char const *vsSource = "#version 450\n"
15175 char const *tcsSource = "#version 450\n"
15176 "layout(location=0) out int x[];\n"
15177 "layout(vertices=3) out;\n"
15179 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15180 " gl_TessLevelInner[0] = 1;\n"
15181 " x[gl_InvocationID] = gl_InvocationID;\n"
15183 char const *tesSource = "#version 450\n"
15184 "layout(triangles, equal_spacing, cw) in;\n"
15185 "layout(location=0) in int x[];\n"
15186 "out gl_PerVertex { vec4 gl_Position; };\n"
15188 " gl_Position.xyz = gl_TessCoord;\n"
15189 " gl_Position.w = x[0] + x[1] + x[2];\n"
15191 char const *fsSource = "#version 450\n"
15192 "layout(location=0) out vec4 color;\n"
15194 " color = vec4(1);\n"
15197 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15198 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15199 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15200 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15202 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15203 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15205 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15207 VkPipelineObj pipe(m_device);
15208 pipe.SetInputAssembly(&iasci);
15209 pipe.SetTessellation(&tsci);
15210 pipe.AddColorAttachment();
15211 pipe.AddShader(&vs);
15212 pipe.AddShader(&tcs);
15213 pipe.AddShader(&tes);
15214 pipe.AddShader(&fs);
15216 VkDescriptorSetObj descriptorSet(m_device);
15217 descriptorSet.AppendDummy();
15218 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15220 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15222 m_errorMonitor->VerifyNotFound();
15225 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
15226 TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
15227 "interface block passed into the geometry shader. This "
15228 "is interesting because the 'extra' array level is not "
15229 "present on the member type, but on the block instance.");
15230 m_errorMonitor->ExpectSuccess();
15232 ASSERT_NO_FATAL_FAILURE(InitState());
15233 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15235 if (!m_device->phy().features().geometryShader) {
15236 printf("Device does not support geometry shaders; skipped.\n");
15240 char const *vsSource = "#version 450\n"
15241 "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
15243 " vs_out.x = vec4(1);\n"
15245 char const *gsSource = "#version 450\n"
15246 "layout(triangles) in;\n"
15247 "layout(triangle_strip, max_vertices=3) out;\n"
15248 "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
15249 "out gl_PerVertex { vec4 gl_Position; };\n"
15251 " gl_Position = gs_in[0].x;\n"
15254 char const *fsSource = "#version 450\n"
15255 "layout(location=0) out vec4 color;\n"
15257 " color = vec4(1);\n"
15260 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15261 VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
15262 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15264 VkPipelineObj pipe(m_device);
15265 pipe.AddColorAttachment();
15266 pipe.AddShader(&vs);
15267 pipe.AddShader(&gs);
15268 pipe.AddShader(&fs);
15270 VkDescriptorSetObj descriptorSet(m_device);
15271 descriptorSet.AppendDummy();
15272 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15274 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15276 m_errorMonitor->VerifyNotFound();
15279 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
15280 TEST_DESCRIPTION("Test that an error is produced for a variable output from "
15281 "the TCS without the patch decoration, but consumed in the TES "
15282 "with the decoration.");
15283 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage "
15284 "but per-patch in tessellation evaluation shader stage");
15286 ASSERT_NO_FATAL_FAILURE(InitState());
15287 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15289 if (!m_device->phy().features().tessellationShader) {
15290 printf("Device does not support tessellation shaders; skipped.\n");
15294 char const *vsSource = "#version 450\n"
15296 char const *tcsSource = "#version 450\n"
15297 "layout(location=0) out int x[];\n"
15298 "layout(vertices=3) out;\n"
15300 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
15301 " gl_TessLevelInner[0] = 1;\n"
15302 " x[gl_InvocationID] = gl_InvocationID;\n"
15304 char const *tesSource = "#version 450\n"
15305 "layout(triangles, equal_spacing, cw) in;\n"
15306 "layout(location=0) patch in int x;\n"
15307 "out gl_PerVertex { vec4 gl_Position; };\n"
15309 " gl_Position.xyz = gl_TessCoord;\n"
15310 " gl_Position.w = x;\n"
15312 char const *fsSource = "#version 450\n"
15313 "layout(location=0) out vec4 color;\n"
15315 " color = vec4(1);\n"
15318 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15319 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
15320 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
15321 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15323 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
15324 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
15326 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
15328 VkPipelineObj pipe(m_device);
15329 pipe.SetInputAssembly(&iasci);
15330 pipe.SetTessellation(&tsci);
15331 pipe.AddColorAttachment();
15332 pipe.AddShader(&vs);
15333 pipe.AddShader(&tcs);
15334 pipe.AddShader(&tes);
15335 pipe.AddShader(&fs);
15337 VkDescriptorSetObj descriptorSet(m_device);
15338 descriptorSet.AppendDummy();
15339 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15341 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15343 m_errorMonitor->VerifyFound();
15346 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
15347 TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
15348 "bindings provide the same location");
15349 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15350 "Duplicate vertex input binding descriptions for binding 0");
15352 ASSERT_NO_FATAL_FAILURE(InitState());
15353 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15355 /* Two binding descriptions for binding 0 */
15356 VkVertexInputBindingDescription input_bindings[2];
15357 memset(input_bindings, 0, sizeof(input_bindings));
15359 VkVertexInputAttributeDescription input_attrib;
15360 memset(&input_attrib, 0, sizeof(input_attrib));
15361 input_attrib.format = VK_FORMAT_R32_SFLOAT;
15363 char const *vsSource = "#version 450\n"
15365 "layout(location=0) in float x;\n" /* attrib provided float */
15366 "out gl_PerVertex {\n"
15367 " vec4 gl_Position;\n"
15370 " gl_Position = vec4(x);\n"
15372 char const *fsSource = "#version 450\n"
15374 "layout(location=0) out vec4 color;\n"
15376 " color = vec4(1);\n"
15379 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15380 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15382 VkPipelineObj pipe(m_device);
15383 pipe.AddColorAttachment();
15384 pipe.AddShader(&vs);
15385 pipe.AddShader(&fs);
15387 pipe.AddVertexInputBindings(input_bindings, 2);
15388 pipe.AddVertexInputAttribs(&input_attrib, 1);
15390 VkDescriptorSetObj descriptorSet(m_device);
15391 descriptorSet.AppendDummy();
15392 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15394 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15396 m_errorMonitor->VerifyFound();
15399 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
15400 TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
15401 "attributes. This is interesting because they consume multiple "
15403 m_errorMonitor->ExpectSuccess();
15405 ASSERT_NO_FATAL_FAILURE(InitState());
15406 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15408 if (!m_device->phy().features().shaderFloat64) {
15409 printf("Device does not support 64bit vertex attributes; skipped.\n");
15413 VkVertexInputBindingDescription input_bindings[1];
15414 memset(input_bindings, 0, sizeof(input_bindings));
15416 VkVertexInputAttributeDescription input_attribs[4];
15417 memset(input_attribs, 0, sizeof(input_attribs));
15418 input_attribs[0].location = 0;
15419 input_attribs[0].offset = 0;
15420 input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15421 input_attribs[1].location = 2;
15422 input_attribs[1].offset = 32;
15423 input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15424 input_attribs[2].location = 4;
15425 input_attribs[2].offset = 64;
15426 input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15427 input_attribs[3].location = 6;
15428 input_attribs[3].offset = 96;
15429 input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
15431 char const *vsSource = "#version 450\n"
15433 "layout(location=0) in dmat4 x;\n"
15434 "out gl_PerVertex {\n"
15435 " vec4 gl_Position;\n"
15438 " gl_Position = vec4(x[0][0]);\n"
15440 char const *fsSource = "#version 450\n"
15442 "layout(location=0) out vec4 color;\n"
15444 " color = vec4(1);\n"
15447 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15448 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15450 VkPipelineObj pipe(m_device);
15451 pipe.AddColorAttachment();
15452 pipe.AddShader(&vs);
15453 pipe.AddShader(&fs);
15455 pipe.AddVertexInputBindings(input_bindings, 1);
15456 pipe.AddVertexInputAttribs(input_attribs, 4);
15458 VkDescriptorSetObj descriptorSet(m_device);
15459 descriptorSet.AppendDummy();
15460 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15462 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15464 m_errorMonitor->VerifyNotFound();
15467 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
15468 TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
15469 "provide an output for one of the pipeline's color attachments");
15470 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
15472 ASSERT_NO_FATAL_FAILURE(InitState());
15474 char const *vsSource = "#version 450\n"
15476 "out gl_PerVertex {\n"
15477 " vec4 gl_Position;\n"
15480 " gl_Position = vec4(1);\n"
15482 char const *fsSource = "#version 450\n"
15487 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15488 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15490 VkPipelineObj pipe(m_device);
15491 pipe.AddShader(&vs);
15492 pipe.AddShader(&fs);
15494 /* set up CB 0, not written */
15495 pipe.AddColorAttachment();
15496 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15498 VkDescriptorSetObj descriptorSet(m_device);
15499 descriptorSet.AppendDummy();
15500 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15502 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15504 m_errorMonitor->VerifyFound();
15507 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
15508 TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
15509 "output with no matching attachment");
15510 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
15511 "FS writes to output location 1 with no matching attachment");
15513 ASSERT_NO_FATAL_FAILURE(InitState());
15515 char const *vsSource = "#version 450\n"
15517 "out gl_PerVertex {\n"
15518 " vec4 gl_Position;\n"
15521 " gl_Position = vec4(1);\n"
15523 char const *fsSource = "#version 450\n"
15525 "layout(location=0) out vec4 x;\n"
15526 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
15532 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15533 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15535 VkPipelineObj pipe(m_device);
15536 pipe.AddShader(&vs);
15537 pipe.AddShader(&fs);
15539 /* set up CB 0, not written */
15540 pipe.AddColorAttachment();
15541 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15542 /* FS writes CB 1, but we don't configure it */
15544 VkDescriptorSetObj descriptorSet(m_device);
15545 descriptorSet.AppendDummy();
15546 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15548 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15550 m_errorMonitor->VerifyFound();
15553 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
15554 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
15555 "type of an FS output variable, and the format of the corresponding attachment");
15556 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
15558 ASSERT_NO_FATAL_FAILURE(InitState());
15560 char const *vsSource = "#version 450\n"
15562 "out gl_PerVertex {\n"
15563 " vec4 gl_Position;\n"
15566 " gl_Position = vec4(1);\n"
15568 char const *fsSource = "#version 450\n"
15570 "layout(location=0) out ivec4 x;\n" /* not UNORM */
15575 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15576 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15578 VkPipelineObj pipe(m_device);
15579 pipe.AddShader(&vs);
15580 pipe.AddShader(&fs);
15582 /* set up CB 0; type is UNORM by default */
15583 pipe.AddColorAttachment();
15584 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15586 VkDescriptorSetObj descriptorSet(m_device);
15587 descriptorSet.AppendDummy();
15588 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15590 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15592 m_errorMonitor->VerifyFound();
15595 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
15596 TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
15597 "block which has no corresponding binding in the pipeline layout");
15598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
15600 ASSERT_NO_FATAL_FAILURE(InitState());
15602 char const *vsSource = "#version 450\n"
15604 "out gl_PerVertex {\n"
15605 " vec4 gl_Position;\n"
15608 " gl_Position = vec4(1);\n"
15610 char const *fsSource = "#version 450\n"
15612 "layout(location=0) out vec4 x;\n"
15613 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
15615 " x = vec4(bar.y);\n"
15618 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15619 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15621 VkPipelineObj pipe(m_device);
15622 pipe.AddShader(&vs);
15623 pipe.AddShader(&fs);
15625 /* set up CB 0; type is UNORM by default */
15626 pipe.AddColorAttachment();
15627 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15629 VkDescriptorSetObj descriptorSet(m_device);
15630 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15632 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15634 m_errorMonitor->VerifyFound();
15637 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
15638 TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
15639 "which are not provided in the pipeline layout");
15640 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
15642 ASSERT_NO_FATAL_FAILURE(InitState());
15644 char const *vsSource = "#version 450\n"
15646 "layout(push_constant, std430) uniform foo { float x; } consts;\n"
15647 "out gl_PerVertex {\n"
15648 " vec4 gl_Position;\n"
15651 " gl_Position = vec4(consts.x);\n"
15653 char const *fsSource = "#version 450\n"
15655 "layout(location=0) out vec4 x;\n"
15660 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15661 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15663 VkPipelineObj pipe(m_device);
15664 pipe.AddShader(&vs);
15665 pipe.AddShader(&fs);
15667 /* set up CB 0; type is UNORM by default */
15668 pipe.AddColorAttachment();
15669 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15671 VkDescriptorSetObj descriptorSet(m_device);
15672 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15674 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
15676 /* should have generated an error -- no push constant ranges provided! */
15677 m_errorMonitor->VerifyFound();
15680 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
15681 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15682 "which is not included in the subpass description");
15683 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15684 "consumes input attachment index 0 but not provided in subpass");
15686 ASSERT_NO_FATAL_FAILURE(InitState());
15688 char const *vsSource = "#version 450\n"
15690 "out gl_PerVertex {\n"
15691 " vec4 gl_Position;\n"
15694 " gl_Position = vec4(1);\n"
15696 char const *fsSource = "#version 450\n"
15698 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15699 "layout(location=0) out vec4 color;\n"
15701 " color = subpassLoad(x);\n"
15704 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15705 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15707 VkPipelineObj pipe(m_device);
15708 pipe.AddShader(&vs);
15709 pipe.AddShader(&fs);
15710 pipe.AddColorAttachment();
15711 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15713 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15714 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15715 VkDescriptorSetLayout dsl;
15716 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15717 ASSERT_VK_SUCCESS(err);
15719 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15720 VkPipelineLayout pl;
15721 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15722 ASSERT_VK_SUCCESS(err);
15725 pipe.CreateVKPipeline(pl, renderPass());
15727 m_errorMonitor->VerifyFound();
15729 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15730 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15733 TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
15734 TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
15735 m_errorMonitor->ExpectSuccess();
15737 ASSERT_NO_FATAL_FAILURE(InitState());
15739 char const *vsSource = "#version 450\n"
15741 "out gl_PerVertex {\n"
15742 " vec4 gl_Position;\n"
15745 " gl_Position = vec4(1);\n"
15747 char const *fsSource = "#version 450\n"
15749 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15750 "layout(location=0) out vec4 color;\n"
15752 " color = subpassLoad(x);\n"
15755 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15756 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15758 VkPipelineObj pipe(m_device);
15759 pipe.AddShader(&vs);
15760 pipe.AddShader(&fs);
15761 pipe.AddColorAttachment();
15762 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15764 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15765 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15766 VkDescriptorSetLayout dsl;
15767 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15768 ASSERT_VK_SUCCESS(err);
15770 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15771 VkPipelineLayout pl;
15772 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15773 ASSERT_VK_SUCCESS(err);
15775 VkAttachmentDescription descs[2] = {
15776 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15777 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15778 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15779 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15780 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15782 VkAttachmentReference color = {
15783 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15785 VkAttachmentReference input = {
15786 1, VK_IMAGE_LAYOUT_GENERAL,
15789 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15791 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15793 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15794 ASSERT_VK_SUCCESS(err);
15796 // should be OK. would go wrong here if it's going to...
15797 pipe.CreateVKPipeline(pl, rp);
15799 m_errorMonitor->VerifyNotFound();
15801 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15802 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15803 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15806 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
15807 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15808 "with a format having a different fundamental type");
15809 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15810 "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
15812 ASSERT_NO_FATAL_FAILURE(InitState());
15814 char const *vsSource = "#version 450\n"
15816 "out gl_PerVertex {\n"
15817 " vec4 gl_Position;\n"
15820 " gl_Position = vec4(1);\n"
15822 char const *fsSource = "#version 450\n"
15824 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
15825 "layout(location=0) out vec4 color;\n"
15827 " color = subpassLoad(x);\n"
15830 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15831 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15833 VkPipelineObj pipe(m_device);
15834 pipe.AddShader(&vs);
15835 pipe.AddShader(&fs);
15836 pipe.AddColorAttachment();
15837 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15839 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15840 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15841 VkDescriptorSetLayout dsl;
15842 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15843 ASSERT_VK_SUCCESS(err);
15845 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15846 VkPipelineLayout pl;
15847 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15848 ASSERT_VK_SUCCESS(err);
15850 VkAttachmentDescription descs[2] = {
15851 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15852 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15853 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
15854 {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
15855 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
15857 VkAttachmentReference color = {
15858 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
15860 VkAttachmentReference input = {
15861 1, VK_IMAGE_LAYOUT_GENERAL,
15864 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
15866 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
15868 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
15869 ASSERT_VK_SUCCESS(err);
15872 pipe.CreateVKPipeline(pl, rp);
15874 m_errorMonitor->VerifyFound();
15876 vkDestroyRenderPass(m_device->device(), rp, nullptr);
15877 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15878 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15881 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
15882 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
15883 "which is not included in the subpass description -- array case");
15884 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
15885 "consumes input attachment index 1 but not provided in subpass");
15887 ASSERT_NO_FATAL_FAILURE(InitState());
15889 char const *vsSource = "#version 450\n"
15891 "out gl_PerVertex {\n"
15892 " vec4 gl_Position;\n"
15895 " gl_Position = vec4(1);\n"
15897 char const *fsSource = "#version 450\n"
15899 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n"
15900 "layout(location=0) out vec4 color;\n"
15902 " color = subpassLoad(xs[1]);\n"
15905 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
15906 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
15908 VkPipelineObj pipe(m_device);
15909 pipe.AddShader(&vs);
15910 pipe.AddShader(&fs);
15911 pipe.AddColorAttachment();
15912 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15914 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
15915 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
15916 VkDescriptorSetLayout dsl;
15917 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
15918 ASSERT_VK_SUCCESS(err);
15920 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
15921 VkPipelineLayout pl;
15922 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
15923 ASSERT_VK_SUCCESS(err);
15926 pipe.CreateVKPipeline(pl, renderPass());
15928 m_errorMonitor->VerifyFound();
15930 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
15931 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
15934 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
15935 TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
15936 "descriptor which is not provided in the pipeline layout");
15937 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
15939 ASSERT_NO_FATAL_FAILURE(InitState());
15941 char const *csSource = "#version 450\n"
15943 "layout(local_size_x=1) in;\n"
15944 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15949 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15951 VkDescriptorSetObj descriptorSet(m_device);
15952 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15954 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15957 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15958 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
15959 descriptorSet.GetPipelineLayout(),
15964 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
15966 m_errorMonitor->VerifyFound();
15968 if (err == VK_SUCCESS) {
15969 vkDestroyPipeline(m_device->device(), pipe, nullptr);
15973 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
15974 TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
15975 "descriptor-backed resource which is not provided, but the shader does not "
15976 "statically use it. This is interesting because it requires compute pipelines "
15977 "to have a proper descriptor use walk, which they didn't for some time.");
15978 m_errorMonitor->ExpectSuccess();
15980 ASSERT_NO_FATAL_FAILURE(InitState());
15982 char const *csSource = "#version 450\n"
15984 "layout(local_size_x=1) in;\n"
15985 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
15987 " // x is not used.\n"
15990 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
15992 VkDescriptorSetObj descriptorSet(m_device);
15993 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
15995 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
15998 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
15999 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16000 descriptorSet.GetPipelineLayout(),
16005 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16007 m_errorMonitor->VerifyNotFound();
16009 if (err == VK_SUCCESS) {
16010 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16014 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
16015 TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
16016 "descriptor-backed resource of a mismatched type");
16017 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16018 "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
16020 ASSERT_NO_FATAL_FAILURE(InitState());
16022 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
16023 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding};
16024 VkDescriptorSetLayout dsl;
16025 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16026 ASSERT_VK_SUCCESS(err);
16028 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16029 VkPipelineLayout pl;
16030 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16031 ASSERT_VK_SUCCESS(err);
16033 char const *csSource = "#version 450\n"
16035 "layout(local_size_x=1) in;\n"
16036 "layout(set=0, binding=0) buffer block { vec4 x; };\n"
16040 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16042 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16045 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16046 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16052 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16054 m_errorMonitor->VerifyFound();
16056 if (err == VK_SUCCESS) {
16057 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16060 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16061 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16064 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
16065 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16066 "sampler portion of a combined image + sampler");
16067 m_errorMonitor->ExpectSuccess();
16069 ASSERT_NO_FATAL_FAILURE(InitState());
16071 VkDescriptorSetLayoutBinding bindings[] = {
16072 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16073 {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16074 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16076 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16077 VkDescriptorSetLayout dsl;
16078 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16079 ASSERT_VK_SUCCESS(err);
16081 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16082 VkPipelineLayout pl;
16083 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16084 ASSERT_VK_SUCCESS(err);
16086 char const *csSource = "#version 450\n"
16088 "layout(local_size_x=1) in;\n"
16089 "layout(set=0, binding=0) uniform sampler s;\n"
16090 "layout(set=0, binding=1) uniform texture2D t;\n"
16091 "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16093 " x = texture(sampler2D(t, s), vec2(0));\n"
16095 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16097 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16100 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16101 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16107 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16109 m_errorMonitor->VerifyNotFound();
16111 if (err == VK_SUCCESS) {
16112 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16115 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16116 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16119 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
16120 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
16121 "image portion of a combined image + sampler");
16122 m_errorMonitor->ExpectSuccess();
16124 ASSERT_NO_FATAL_FAILURE(InitState());
16126 VkDescriptorSetLayoutBinding bindings[] = {
16127 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16128 {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16129 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16131 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
16132 VkDescriptorSetLayout dsl;
16133 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16134 ASSERT_VK_SUCCESS(err);
16136 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16137 VkPipelineLayout pl;
16138 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16139 ASSERT_VK_SUCCESS(err);
16141 char const *csSource = "#version 450\n"
16143 "layout(local_size_x=1) in;\n"
16144 "layout(set=0, binding=0) uniform texture2D t;\n"
16145 "layout(set=0, binding=1) uniform sampler s;\n"
16146 "layout(set=0, binding=2) buffer block { vec4 x; };\n"
16148 " x = texture(sampler2D(t, s), vec2(0));\n"
16150 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16152 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16155 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16156 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16162 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16164 m_errorMonitor->VerifyNotFound();
16166 if (err == VK_SUCCESS) {
16167 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16170 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16171 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16174 TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
16175 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
16176 "both the sampler and the image of a combined image+sampler "
16177 "but via separate variables");
16178 m_errorMonitor->ExpectSuccess();
16180 ASSERT_NO_FATAL_FAILURE(InitState());
16182 VkDescriptorSetLayoutBinding bindings[] = {
16183 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16184 {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
16186 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
16187 VkDescriptorSetLayout dsl;
16188 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
16189 ASSERT_VK_SUCCESS(err);
16191 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
16192 VkPipelineLayout pl;
16193 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
16194 ASSERT_VK_SUCCESS(err);
16196 char const *csSource = "#version 450\n"
16198 "layout(local_size_x=1) in;\n"
16199 "layout(set=0, binding=0) uniform texture2D t;\n"
16200 "layout(set=0, binding=0) uniform sampler s; // both binding 0!\n"
16201 "layout(set=0, binding=1) buffer block { vec4 x; };\n"
16203 " x = texture(sampler2D(t, s), vec2(0));\n"
16205 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
16207 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
16210 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
16211 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
16217 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
16219 m_errorMonitor->VerifyNotFound();
16221 if (err == VK_SUCCESS) {
16222 vkDestroyPipeline(m_device->device(), pipe, nullptr);
16225 vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
16226 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
16229 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
16230 TEST_DESCRIPTION("Test that an error is produced when an image view type "
16231 "does not match the dimensionality declared in the shader");
16233 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
16235 ASSERT_NO_FATAL_FAILURE(InitState());
16236 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16238 char const *vsSource = "#version 450\n"
16240 "out gl_PerVertex { vec4 gl_Position; };\n"
16241 "void main() { gl_Position = vec4(0); }\n";
16242 char const *fsSource = "#version 450\n"
16244 "layout(set=0, binding=0) uniform sampler3D s;\n"
16245 "layout(location=0) out vec4 color;\n"
16247 " color = texture(s, vec3(0));\n"
16249 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16250 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16252 VkPipelineObj pipe(m_device);
16253 pipe.AddShader(&vs);
16254 pipe.AddShader(&fs);
16255 pipe.AddColorAttachment();
16257 VkTextureObj texture(m_device, nullptr);
16258 VkSamplerObj sampler(m_device);
16260 VkDescriptorSetObj descriptorSet(m_device);
16261 descriptorSet.AppendSamplerTexture(&sampler, &texture);
16262 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16264 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16265 ASSERT_VK_SUCCESS(err);
16267 BeginCommandBuffer();
16269 m_commandBuffer->BindPipeline(pipe);
16270 m_commandBuffer->BindDescriptorSet(descriptorSet);
16272 VkViewport viewport = {0, 0, 16, 16, 0, 1};
16273 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16274 VkRect2D scissor = {{0, 0}, {16, 16}};
16275 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16277 // error produced here.
16278 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16280 m_errorMonitor->VerifyFound();
16282 EndCommandBuffer();
16285 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
16286 TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
16287 "are consumed via singlesample images types in the shader, or vice versa.");
16289 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
16291 ASSERT_NO_FATAL_FAILURE(InitState());
16292 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16294 char const *vsSource = "#version 450\n"
16296 "out gl_PerVertex { vec4 gl_Position; };\n"
16297 "void main() { gl_Position = vec4(0); }\n";
16298 char const *fsSource = "#version 450\n"
16300 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
16301 "layout(location=0) out vec4 color;\n"
16303 " color = texelFetch(s, ivec2(0), 0);\n"
16305 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
16306 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
16308 VkPipelineObj pipe(m_device);
16309 pipe.AddShader(&vs);
16310 pipe.AddShader(&fs);
16311 pipe.AddColorAttachment();
16313 VkTextureObj texture(m_device, nullptr);
16314 VkSamplerObj sampler(m_device);
16316 VkDescriptorSetObj descriptorSet(m_device);
16317 descriptorSet.AppendSamplerTexture(&sampler, &texture);
16318 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
16320 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
16321 ASSERT_VK_SUCCESS(err);
16323 BeginCommandBuffer();
16325 m_commandBuffer->BindPipeline(pipe);
16326 m_commandBuffer->BindDescriptorSet(descriptorSet);
16328 VkViewport viewport = {0, 0, 16, 16, 0, 1};
16329 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16330 VkRect2D scissor = {{0, 0}, {16, 16}};
16331 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16333 // error produced here.
16334 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
16336 m_errorMonitor->VerifyFound();
16338 EndCommandBuffer();
16341 #endif // SHADER_CHECKER_TESTS
16343 #if DEVICE_LIMITS_TESTS
16344 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) {
16345 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16347 ASSERT_NO_FATAL_FAILURE(InitState());
16352 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16353 const int32_t tex_width = 32;
16354 const int32_t tex_height = 32;
16356 VkImageCreateInfo image_create_info = {};
16357 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16358 image_create_info.pNext = NULL;
16359 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16360 image_create_info.format = tex_format;
16361 image_create_info.extent.width = tex_width;
16362 image_create_info.extent.height = tex_height;
16363 image_create_info.extent.depth = 1;
16364 image_create_info.mipLevels = 1;
16365 image_create_info.arrayLayers = 1;
16366 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16367 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16368 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16369 image_create_info.flags = 0;
16371 // Introduce error by sending down a bogus width extent
16372 image_create_info.extent.width = 65536;
16373 vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16375 m_errorMonitor->VerifyFound();
16378 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) {
16379 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16380 "CreateImage extents is 0 for at least one required dimension");
16382 ASSERT_NO_FATAL_FAILURE(InitState());
16387 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16388 const int32_t tex_width = 32;
16389 const int32_t tex_height = 32;
16391 VkImageCreateInfo image_create_info = {};
16392 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16393 image_create_info.pNext = NULL;
16394 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16395 image_create_info.format = tex_format;
16396 image_create_info.extent.width = tex_width;
16397 image_create_info.extent.height = tex_height;
16398 image_create_info.extent.depth = 1;
16399 image_create_info.mipLevels = 1;
16400 image_create_info.arrayLayers = 1;
16401 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16402 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16403 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16404 image_create_info.flags = 0;
16406 // Introduce error by sending down a bogus width extent
16407 image_create_info.extent.width = 0;
16408 vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16410 m_errorMonitor->VerifyFound();
16412 #endif // DEVICE_LIMITS_TESTS
16415 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
16416 TEST_DESCRIPTION("Create a render pass with an attachment description "
16417 "format set to VK_FORMAT_UNDEFINED");
16419 ASSERT_NO_FATAL_FAILURE(InitState());
16420 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16422 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
16424 VkAttachmentReference color_attach = {};
16425 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
16426 color_attach.attachment = 0;
16427 VkSubpassDescription subpass = {};
16428 subpass.colorAttachmentCount = 1;
16429 subpass.pColorAttachments = &color_attach;
16431 VkRenderPassCreateInfo rpci = {};
16432 rpci.subpassCount = 1;
16433 rpci.pSubpasses = &subpass;
16434 rpci.attachmentCount = 1;
16435 VkAttachmentDescription attach_desc = {};
16436 attach_desc.format = VK_FORMAT_UNDEFINED;
16437 rpci.pAttachments = &attach_desc;
16438 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16440 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16442 m_errorMonitor->VerifyFound();
16444 if (result == VK_SUCCESS) {
16445 vkDestroyRenderPass(m_device->device(), rp, NULL);
16449 TEST_F(VkLayerTest, InvalidImageView) {
16452 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 ");
16454 ASSERT_NO_FATAL_FAILURE(InitState());
16456 // Create an image and try to create a view with bad baseMipLevel
16459 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16460 const int32_t tex_width = 32;
16461 const int32_t tex_height = 32;
16463 VkImageCreateInfo image_create_info = {};
16464 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16465 image_create_info.pNext = NULL;
16466 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16467 image_create_info.format = tex_format;
16468 image_create_info.extent.width = tex_width;
16469 image_create_info.extent.height = tex_height;
16470 image_create_info.extent.depth = 1;
16471 image_create_info.mipLevels = 1;
16472 image_create_info.arrayLayers = 1;
16473 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16474 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16475 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16476 image_create_info.flags = 0;
16478 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16479 ASSERT_VK_SUCCESS(err);
16481 VkImageViewCreateInfo image_view_create_info = {};
16482 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16483 image_view_create_info.image = image;
16484 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16485 image_view_create_info.format = tex_format;
16486 image_view_create_info.subresourceRange.layerCount = 1;
16487 image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error
16488 image_view_create_info.subresourceRange.levelCount = 1;
16489 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16492 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16494 m_errorMonitor->VerifyFound();
16495 vkDestroyImage(m_device->device(), image, NULL);
16498 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
16500 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16501 " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
16503 ASSERT_NO_FATAL_FAILURE(InitState());
16505 // Create an image and try to create a view with no memory backing the image
16508 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16509 const int32_t tex_width = 32;
16510 const int32_t tex_height = 32;
16512 VkImageCreateInfo image_create_info = {};
16513 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16514 image_create_info.pNext = NULL;
16515 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16516 image_create_info.format = tex_format;
16517 image_create_info.extent.width = tex_width;
16518 image_create_info.extent.height = tex_height;
16519 image_create_info.extent.depth = 1;
16520 image_create_info.mipLevels = 1;
16521 image_create_info.arrayLayers = 1;
16522 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16523 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16524 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
16525 image_create_info.flags = 0;
16527 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
16528 ASSERT_VK_SUCCESS(err);
16530 VkImageViewCreateInfo image_view_create_info = {};
16531 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16532 image_view_create_info.image = image;
16533 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16534 image_view_create_info.format = tex_format;
16535 image_view_create_info.subresourceRange.layerCount = 1;
16536 image_view_create_info.subresourceRange.baseMipLevel = 0;
16537 image_view_create_info.subresourceRange.levelCount = 1;
16538 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16541 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16543 m_errorMonitor->VerifyFound();
16544 vkDestroyImage(m_device->device(), image, NULL);
16545 // If last error is success, it still created the view, so delete it.
16546 if (err == VK_SUCCESS) {
16547 vkDestroyImageView(m_device->device(), view, NULL);
16551 TEST_F(VkLayerTest, InvalidImageViewAspect) {
16552 TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
16553 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image "
16554 "formats must have ONLY the "
16555 "VK_IMAGE_ASPECT_COLOR_BIT set");
16557 ASSERT_NO_FATAL_FAILURE(InitState());
16559 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
16560 VkImageObj image(m_device);
16561 image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
16562 ASSERT_TRUE(image.initialized());
16564 VkImageViewCreateInfo image_view_create_info = {};
16565 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16566 image_view_create_info.image = image.handle();
16567 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
16568 image_view_create_info.format = tex_format;
16569 image_view_create_info.subresourceRange.baseMipLevel = 0;
16570 image_view_create_info.subresourceRange.levelCount = 1;
16571 // Cause an error by setting an invalid image aspect
16572 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16575 vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
16577 m_errorMonitor->VerifyFound();
16580 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
16584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16585 "vkCmdCopyImage: number of layers in source and destination subresources for pRegions");
16587 ASSERT_NO_FATAL_FAILURE(InitState());
16589 // Create two images of different types and try to copy between them
16592 VkDeviceMemory srcMem;
16593 VkDeviceMemory destMem;
16594 VkMemoryRequirements memReqs;
16596 VkImageCreateInfo image_create_info = {};
16597 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16598 image_create_info.pNext = NULL;
16599 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16600 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16601 image_create_info.extent.width = 32;
16602 image_create_info.extent.height = 32;
16603 image_create_info.extent.depth = 1;
16604 image_create_info.mipLevels = 1;
16605 image_create_info.arrayLayers = 4;
16606 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16607 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16608 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16609 image_create_info.flags = 0;
16611 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
16612 ASSERT_VK_SUCCESS(err);
16614 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
16615 ASSERT_VK_SUCCESS(err);
16618 VkMemoryAllocateInfo memAlloc = {};
16619 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16620 memAlloc.pNext = NULL;
16621 memAlloc.allocationSize = 0;
16622 memAlloc.memoryTypeIndex = 0;
16624 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
16625 memAlloc.allocationSize = memReqs.size;
16626 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16628 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
16629 ASSERT_VK_SUCCESS(err);
16631 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
16632 memAlloc.allocationSize = memReqs.size;
16633 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
16634 ASSERT_VK_SUCCESS(err);
16635 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
16636 ASSERT_VK_SUCCESS(err);
16638 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
16639 ASSERT_VK_SUCCESS(err);
16640 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
16641 ASSERT_VK_SUCCESS(err);
16643 BeginCommandBuffer();
16644 VkImageCopy copyRegion;
16645 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16646 copyRegion.srcSubresource.mipLevel = 0;
16647 copyRegion.srcSubresource.baseArrayLayer = 0;
16648 copyRegion.srcSubresource.layerCount = 1;
16649 copyRegion.srcOffset.x = 0;
16650 copyRegion.srcOffset.y = 0;
16651 copyRegion.srcOffset.z = 0;
16652 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16653 copyRegion.dstSubresource.mipLevel = 0;
16654 copyRegion.dstSubresource.baseArrayLayer = 0;
16655 // Introduce failure by forcing the dst layerCount to differ from src
16656 copyRegion.dstSubresource.layerCount = 3;
16657 copyRegion.dstOffset.x = 0;
16658 copyRegion.dstOffset.y = 0;
16659 copyRegion.dstOffset.z = 0;
16660 copyRegion.extent.width = 1;
16661 copyRegion.extent.height = 1;
16662 copyRegion.extent.depth = 1;
16663 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
16664 EndCommandBuffer();
16666 m_errorMonitor->VerifyFound();
16668 vkDestroyImage(m_device->device(), srcImage, NULL);
16669 vkDestroyImage(m_device->device(), dstImage, NULL);
16670 vkFreeMemory(m_device->device(), srcMem, NULL);
16671 vkFreeMemory(m_device->device(), destMem, NULL);
16674 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
16676 TEST_DESCRIPTION("Creating images with unsuported formats ");
16678 ASSERT_NO_FATAL_FAILURE(InitState());
16679 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16680 VkImageObj image(m_device);
16681 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16682 VK_IMAGE_TILING_OPTIMAL, 0);
16683 ASSERT_TRUE(image.initialized());
16685 // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
16686 VkImageCreateInfo image_create_info;
16687 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16688 image_create_info.pNext = NULL;
16689 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16690 image_create_info.format = VK_FORMAT_UNDEFINED;
16691 image_create_info.extent.width = 32;
16692 image_create_info.extent.height = 32;
16693 image_create_info.extent.depth = 1;
16694 image_create_info.mipLevels = 1;
16695 image_create_info.arrayLayers = 1;
16696 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16697 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
16698 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16699 image_create_info.flags = 0;
16701 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16702 "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
16704 VkImage localImage;
16705 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16706 m_errorMonitor->VerifyFound();
16708 VkFormat unsupported = VK_FORMAT_UNDEFINED;
16709 // Look for a format that is COMPLETELY unsupported with this hardware
16710 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
16711 VkFormat format = static_cast<VkFormat>(f);
16712 VkFormatProperties fProps = m_device->format_properties(format);
16713 if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
16714 unsupported = format;
16719 if (unsupported != VK_FORMAT_UNDEFINED) {
16720 image_create_info.format = unsupported;
16721 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
16723 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage);
16724 m_errorMonitor->VerifyFound();
16728 TEST_F(VkLayerTest, ImageLayerViewTests) {
16730 TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
16732 ASSERT_NO_FATAL_FAILURE(InitState());
16734 VkImageObj image(m_device);
16735 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16736 VK_IMAGE_TILING_OPTIMAL, 0);
16737 ASSERT_TRUE(image.initialized());
16739 VkImageView imgView;
16740 VkImageViewCreateInfo imgViewInfo = {};
16741 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16742 imgViewInfo.image = image.handle();
16743 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
16744 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16745 imgViewInfo.subresourceRange.layerCount = 1;
16746 imgViewInfo.subresourceRange.baseMipLevel = 0;
16747 imgViewInfo.subresourceRange.levelCount = 1;
16748 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel");
16751 // View can't have baseMipLevel >= image's mipLevels - Expect
16752 // VIEW_CREATE_ERROR
16753 imgViewInfo.subresourceRange.baseMipLevel = 1;
16754 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16755 m_errorMonitor->VerifyFound();
16756 imgViewInfo.subresourceRange.baseMipLevel = 0;
16758 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer");
16759 // View can't have baseArrayLayer >= image's arraySize - Expect
16760 // VIEW_CREATE_ERROR
16761 imgViewInfo.subresourceRange.baseArrayLayer = 1;
16762 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16763 m_errorMonitor->VerifyFound();
16764 imgViewInfo.subresourceRange.baseArrayLayer = 0;
16766 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16767 "pCreateInfo->subresourceRange."
16769 // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR
16770 imgViewInfo.subresourceRange.levelCount = 0;
16771 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16772 m_errorMonitor->VerifyFound();
16773 imgViewInfo.subresourceRange.levelCount = 1;
16775 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in "
16776 "pCreateInfo->subresourceRange."
16778 // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR
16779 imgViewInfo.subresourceRange.layerCount = 0;
16780 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16781 m_errorMonitor->VerifyFound();
16782 imgViewInfo.subresourceRange.layerCount = 1;
16784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats");
16785 // Can't use depth format for view into color image - Expect INVALID_FORMAT
16786 imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
16787 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16788 m_errorMonitor->VerifyFound();
16789 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless "
16792 "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT "
16793 "was set on image creation.");
16794 // Same compatibility class but no MUTABLE_FORMAT bit - Expect
16795 // VIEW_CREATE_ERROR
16796 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
16797 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16798 m_errorMonitor->VerifyFound();
16799 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
16801 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with "
16802 "differing formats but they must be "
16803 "in the same compatibility class.");
16804 // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect
16805 // VIEW_CREATE_ERROR
16806 VkImageCreateInfo mutImgInfo = image.create_info();
16808 mutImgInfo.format = VK_FORMAT_R8_UINT;
16809 assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
16810 mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
16811 mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
16812 ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage);
16813 ASSERT_VK_SUCCESS(ret);
16814 imgViewInfo.image = mutImage;
16815 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
16816 m_errorMonitor->VerifyFound();
16817 imgViewInfo.image = image.handle();
16818 vkDestroyImage(m_device->handle(), mutImage, NULL);
16821 TEST_F(VkLayerTest, MiscImageLayerTests) {
16823 TEST_DESCRIPTION("Image layer tests that don't belong elsewhare");
16825 ASSERT_NO_FATAL_FAILURE(InitState());
16827 VkImageObj image(m_device);
16828 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
16829 VK_IMAGE_TILING_OPTIMAL, 0);
16830 ASSERT_TRUE(image.initialized());
16832 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero");
16833 vk_testing::Buffer buffer;
16834 VkMemoryPropertyFlags reqs = 0;
16835 buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
16836 VkBufferImageCopy region = {};
16837 region.bufferRowLength = 128;
16838 region.bufferImageHeight = 128;
16839 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16840 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
16841 region.imageSubresource.layerCount = 0;
16842 region.imageExtent.height = 4;
16843 region.imageExtent.width = 4;
16844 region.imageExtent.depth = 1;
16845 m_commandBuffer->BeginCommandBuffer();
16846 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16847 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16848 m_errorMonitor->VerifyFound();
16849 region.imageSubresource.layerCount = 1;
16851 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
16852 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
16853 region.bufferOffset = 6;
16854 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size");
16855 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16856 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16857 m_errorMonitor->VerifyFound();
16859 // BufferOffset must be a multiple of 4
16860 // Introduce failure by setting bufferOffset to a value not divisible by 4
16861 region.bufferOffset = 6;
16862 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4");
16863 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16864 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16865 m_errorMonitor->VerifyFound();
16867 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
16868 region.bufferOffset = 0;
16869 region.imageExtent.height = 128;
16870 region.imageExtent.width = 128;
16871 // Introduce failure by setting bufferRowLength > 0 but less than width
16872 region.bufferRowLength = 64;
16873 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16874 "must be zero or greater-than-or-equal-to imageExtent.width");
16875 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16876 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16877 m_errorMonitor->VerifyFound();
16879 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
16880 region.bufferRowLength = 128;
16881 // Introduce failure by setting bufferRowHeight > 0 but less than height
16882 region.bufferImageHeight = 64;
16883 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16884 "must be zero or greater-than-or-equal-to imageExtent.height");
16885 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16886 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16887 m_errorMonitor->VerifyFound();
16889 region.bufferImageHeight = 128;
16890 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must "
16891 "specify only COLOR or DEPTH or "
16893 // Expect MISMATCHED_IMAGE_ASPECT
16894 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
16895 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
16896 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
16897 m_errorMonitor->VerifyFound();
16898 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16900 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16901 "If the format of srcImage is a depth, stencil, depth stencil or "
16902 "integer-based format then filter must be VK_FILTER_NEAREST");
16903 // Expect INVALID_FILTER
16904 VkImageObj intImage1(m_device);
16905 intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16906 VkImageObj intImage2(m_device);
16907 intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16908 VkImageBlit blitRegion = {};
16909 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16910 blitRegion.srcSubresource.baseArrayLayer = 0;
16911 blitRegion.srcSubresource.layerCount = 1;
16912 blitRegion.srcSubresource.mipLevel = 0;
16913 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16914 blitRegion.dstSubresource.baseArrayLayer = 0;
16915 blitRegion.dstSubresource.layerCount = 1;
16916 blitRegion.dstSubresource.mipLevel = 0;
16918 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16919 intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR);
16920 m_errorMonitor->VerifyFound();
16922 // Look for NULL-blit warning
16923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area.");
16924 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(),
16925 intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR);
16926 m_errorMonitor->VerifyFound();
16928 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers");
16929 VkImageMemoryBarrier img_barrier;
16930 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
16931 img_barrier.pNext = NULL;
16932 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
16933 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
16934 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16935 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
16936 img_barrier.image = image.handle();
16937 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16938 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
16939 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
16940 img_barrier.subresourceRange.baseArrayLayer = 0;
16941 img_barrier.subresourceRange.baseMipLevel = 0;
16942 // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE
16943 img_barrier.subresourceRange.layerCount = 0;
16944 img_barrier.subresourceRange.levelCount = 1;
16945 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
16946 nullptr, 0, nullptr, 1, &img_barrier);
16947 m_errorMonitor->VerifyFound();
16948 img_barrier.subresourceRange.layerCount = 1;
16951 TEST_F(VkLayerTest, ImageFormatLimits) {
16953 TEST_DESCRIPTION("Exceed the limits of image format ");
16955 ASSERT_NO_FATAL_FAILURE(InitState());
16956 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format");
16957 VkImageCreateInfo image_create_info = {};
16958 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
16959 image_create_info.pNext = NULL;
16960 image_create_info.imageType = VK_IMAGE_TYPE_2D;
16961 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
16962 image_create_info.extent.width = 32;
16963 image_create_info.extent.height = 32;
16964 image_create_info.extent.depth = 1;
16965 image_create_info.mipLevels = 1;
16966 image_create_info.arrayLayers = 1;
16967 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
16968 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
16969 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
16970 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
16971 image_create_info.flags = 0;
16974 VkImageFormatProperties imgFmtProps;
16975 vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
16976 image_create_info.usage, image_create_info.flags, &imgFmtProps);
16977 image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1;
16978 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16979 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16980 m_errorMonitor->VerifyFound();
16981 image_create_info.extent.depth = 1;
16983 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16984 image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
16985 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16986 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16987 m_errorMonitor->VerifyFound();
16988 image_create_info.mipLevels = 1;
16990 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of");
16991 image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
16992 // Expect INVALID_FORMAT_LIMITS_VIOLATION
16993 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
16994 m_errorMonitor->VerifyFound();
16995 image_create_info.arrayLayers = 1;
16997 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format");
16998 int samples = imgFmtProps.sampleCounts >> 1;
16999 image_create_info.samples = (VkSampleCountFlagBits)samples;
17000 // Expect INVALID_FORMAT_LIMITS_VIOLATION
17001 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17002 m_errorMonitor->VerifyFound();
17003 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17005 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be "
17006 "VK_IMAGE_LAYOUT_UNDEFINED or "
17007 "VK_IMAGE_LAYOUT_PREINITIALIZED");
17008 image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
17009 // Expect INVALID_LAYOUT
17010 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
17011 m_errorMonitor->VerifyFound();
17012 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17015 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
17019 // Create color images with different format sizes and try to copy between them
17020 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17021 "vkCmdCopyImage called with unmatched source and dest image format sizes");
17023 ASSERT_NO_FATAL_FAILURE(InitState());
17025 // Create two images of different types and try to copy between them
17028 VkDeviceMemory srcMem;
17029 VkDeviceMemory destMem;
17030 VkMemoryRequirements memReqs;
17032 VkImageCreateInfo image_create_info = {};
17033 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17034 image_create_info.pNext = NULL;
17035 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17036 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17037 image_create_info.extent.width = 32;
17038 image_create_info.extent.height = 32;
17039 image_create_info.extent.depth = 1;
17040 image_create_info.mipLevels = 1;
17041 image_create_info.arrayLayers = 1;
17042 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17043 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17044 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17045 image_create_info.flags = 0;
17047 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17048 ASSERT_VK_SUCCESS(err);
17050 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17051 // Introduce failure by creating second image with a different-sized format.
17052 image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
17054 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17055 ASSERT_VK_SUCCESS(err);
17058 VkMemoryAllocateInfo memAlloc = {};
17059 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17060 memAlloc.pNext = NULL;
17061 memAlloc.allocationSize = 0;
17062 memAlloc.memoryTypeIndex = 0;
17064 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17065 memAlloc.allocationSize = memReqs.size;
17066 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17068 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17069 ASSERT_VK_SUCCESS(err);
17071 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17072 memAlloc.allocationSize = memReqs.size;
17073 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17075 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17076 ASSERT_VK_SUCCESS(err);
17078 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17079 ASSERT_VK_SUCCESS(err);
17080 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17081 ASSERT_VK_SUCCESS(err);
17083 BeginCommandBuffer();
17084 VkImageCopy copyRegion;
17085 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17086 copyRegion.srcSubresource.mipLevel = 0;
17087 copyRegion.srcSubresource.baseArrayLayer = 0;
17088 copyRegion.srcSubresource.layerCount = 0;
17089 copyRegion.srcOffset.x = 0;
17090 copyRegion.srcOffset.y = 0;
17091 copyRegion.srcOffset.z = 0;
17092 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17093 copyRegion.dstSubresource.mipLevel = 0;
17094 copyRegion.dstSubresource.baseArrayLayer = 0;
17095 copyRegion.dstSubresource.layerCount = 0;
17096 copyRegion.dstOffset.x = 0;
17097 copyRegion.dstOffset.y = 0;
17098 copyRegion.dstOffset.z = 0;
17099 copyRegion.extent.width = 1;
17100 copyRegion.extent.height = 1;
17101 copyRegion.extent.depth = 1;
17102 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
17103 EndCommandBuffer();
17105 m_errorMonitor->VerifyFound();
17107 vkDestroyImage(m_device->device(), srcImage, NULL);
17108 vkDestroyImage(m_device->device(), dstImage, NULL);
17109 vkFreeMemory(m_device->device(), srcMem, NULL);
17110 vkFreeMemory(m_device->device(), destMem, NULL);
17113 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
17117 // Create a color image and a depth/stencil image and try to copy between them
17118 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17119 "vkCmdCopyImage called with unmatched source and dest image depth");
17121 ASSERT_NO_FATAL_FAILURE(InitState());
17123 // Create two images of different types and try to copy between them
17126 VkDeviceMemory srcMem;
17127 VkDeviceMemory destMem;
17128 VkMemoryRequirements memReqs;
17130 VkImageCreateInfo image_create_info = {};
17131 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17132 image_create_info.pNext = NULL;
17133 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17134 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17135 image_create_info.extent.width = 32;
17136 image_create_info.extent.height = 32;
17137 image_create_info.extent.depth = 1;
17138 image_create_info.mipLevels = 1;
17139 image_create_info.arrayLayers = 1;
17140 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17141 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17142 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17143 image_create_info.flags = 0;
17145 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17146 ASSERT_VK_SUCCESS(err);
17148 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17150 // Introduce failure by creating second image with a depth/stencil format
17151 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17152 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17153 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17155 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17156 ASSERT_VK_SUCCESS(err);
17159 VkMemoryAllocateInfo memAlloc = {};
17160 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17161 memAlloc.pNext = NULL;
17162 memAlloc.allocationSize = 0;
17163 memAlloc.memoryTypeIndex = 0;
17165 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17166 memAlloc.allocationSize = memReqs.size;
17167 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17169 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17170 ASSERT_VK_SUCCESS(err);
17172 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17173 memAlloc.allocationSize = memReqs.size;
17174 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17176 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17177 ASSERT_VK_SUCCESS(err);
17179 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17180 ASSERT_VK_SUCCESS(err);
17181 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17182 ASSERT_VK_SUCCESS(err);
17184 BeginCommandBuffer();
17185 VkImageCopy copyRegion;
17186 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17187 copyRegion.srcSubresource.mipLevel = 0;
17188 copyRegion.srcSubresource.baseArrayLayer = 0;
17189 copyRegion.srcSubresource.layerCount = 0;
17190 copyRegion.srcOffset.x = 0;
17191 copyRegion.srcOffset.y = 0;
17192 copyRegion.srcOffset.z = 0;
17193 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17194 copyRegion.dstSubresource.mipLevel = 0;
17195 copyRegion.dstSubresource.baseArrayLayer = 0;
17196 copyRegion.dstSubresource.layerCount = 0;
17197 copyRegion.dstOffset.x = 0;
17198 copyRegion.dstOffset.y = 0;
17199 copyRegion.dstOffset.z = 0;
17200 copyRegion.extent.width = 1;
17201 copyRegion.extent.height = 1;
17202 copyRegion.extent.depth = 1;
17203 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
17204 EndCommandBuffer();
17206 m_errorMonitor->VerifyFound();
17208 vkDestroyImage(m_device->device(), srcImage, NULL);
17209 vkDestroyImage(m_device->device(), dstImage, NULL);
17210 vkFreeMemory(m_device->device(), srcMem, NULL);
17211 vkFreeMemory(m_device->device(), destMem, NULL);
17214 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
17218 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17219 "vkCmdResolveImage called with source sample count less than 2.");
17221 ASSERT_NO_FATAL_FAILURE(InitState());
17223 // Create two images of sample count 1 and try to Resolve between them
17226 VkDeviceMemory srcMem;
17227 VkDeviceMemory destMem;
17228 VkMemoryRequirements memReqs;
17230 VkImageCreateInfo image_create_info = {};
17231 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17232 image_create_info.pNext = NULL;
17233 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17234 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17235 image_create_info.extent.width = 32;
17236 image_create_info.extent.height = 1;
17237 image_create_info.extent.depth = 1;
17238 image_create_info.mipLevels = 1;
17239 image_create_info.arrayLayers = 1;
17240 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17241 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17242 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17243 image_create_info.flags = 0;
17245 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17246 ASSERT_VK_SUCCESS(err);
17248 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17250 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17251 ASSERT_VK_SUCCESS(err);
17254 VkMemoryAllocateInfo memAlloc = {};
17255 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17256 memAlloc.pNext = NULL;
17257 memAlloc.allocationSize = 0;
17258 memAlloc.memoryTypeIndex = 0;
17260 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17261 memAlloc.allocationSize = memReqs.size;
17262 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17264 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17265 ASSERT_VK_SUCCESS(err);
17267 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17268 memAlloc.allocationSize = memReqs.size;
17269 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17271 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17272 ASSERT_VK_SUCCESS(err);
17274 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17275 ASSERT_VK_SUCCESS(err);
17276 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17277 ASSERT_VK_SUCCESS(err);
17279 BeginCommandBuffer();
17280 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17281 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17282 // VK_IMAGE_LAYOUT_GENERAL = 1,
17283 VkImageResolve resolveRegion;
17284 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17285 resolveRegion.srcSubresource.mipLevel = 0;
17286 resolveRegion.srcSubresource.baseArrayLayer = 0;
17287 resolveRegion.srcSubresource.layerCount = 1;
17288 resolveRegion.srcOffset.x = 0;
17289 resolveRegion.srcOffset.y = 0;
17290 resolveRegion.srcOffset.z = 0;
17291 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17292 resolveRegion.dstSubresource.mipLevel = 0;
17293 resolveRegion.dstSubresource.baseArrayLayer = 0;
17294 resolveRegion.dstSubresource.layerCount = 1;
17295 resolveRegion.dstOffset.x = 0;
17296 resolveRegion.dstOffset.y = 0;
17297 resolveRegion.dstOffset.z = 0;
17298 resolveRegion.extent.width = 1;
17299 resolveRegion.extent.height = 1;
17300 resolveRegion.extent.depth = 1;
17301 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17302 EndCommandBuffer();
17304 m_errorMonitor->VerifyFound();
17306 vkDestroyImage(m_device->device(), srcImage, NULL);
17307 vkDestroyImage(m_device->device(), dstImage, NULL);
17308 vkFreeMemory(m_device->device(), srcMem, NULL);
17309 vkFreeMemory(m_device->device(), destMem, NULL);
17312 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
17316 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17317 "vkCmdResolveImage called with dest sample count greater than 1.");
17319 ASSERT_NO_FATAL_FAILURE(InitState());
17321 // Create two images of sample count 4 and try to Resolve between them
17324 VkDeviceMemory srcMem;
17325 VkDeviceMemory destMem;
17326 VkMemoryRequirements memReqs;
17328 VkImageCreateInfo image_create_info = {};
17329 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17330 image_create_info.pNext = NULL;
17331 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17332 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17333 image_create_info.extent.width = 32;
17334 image_create_info.extent.height = 1;
17335 image_create_info.extent.depth = 1;
17336 image_create_info.mipLevels = 1;
17337 image_create_info.arrayLayers = 1;
17338 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
17339 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17340 // Note: Some implementations expect color attachment usage for any
17341 // multisample surface
17342 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17343 image_create_info.flags = 0;
17345 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17346 ASSERT_VK_SUCCESS(err);
17348 // Note: Some implementations expect color attachment usage for any
17349 // multisample surface
17350 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17352 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17353 ASSERT_VK_SUCCESS(err);
17356 VkMemoryAllocateInfo memAlloc = {};
17357 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17358 memAlloc.pNext = NULL;
17359 memAlloc.allocationSize = 0;
17360 memAlloc.memoryTypeIndex = 0;
17362 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17363 memAlloc.allocationSize = memReqs.size;
17364 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17366 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17367 ASSERT_VK_SUCCESS(err);
17369 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17370 memAlloc.allocationSize = memReqs.size;
17371 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17373 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17374 ASSERT_VK_SUCCESS(err);
17376 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17377 ASSERT_VK_SUCCESS(err);
17378 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17379 ASSERT_VK_SUCCESS(err);
17381 BeginCommandBuffer();
17382 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17383 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17384 // VK_IMAGE_LAYOUT_GENERAL = 1,
17385 VkImageResolve resolveRegion;
17386 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17387 resolveRegion.srcSubresource.mipLevel = 0;
17388 resolveRegion.srcSubresource.baseArrayLayer = 0;
17389 resolveRegion.srcSubresource.layerCount = 1;
17390 resolveRegion.srcOffset.x = 0;
17391 resolveRegion.srcOffset.y = 0;
17392 resolveRegion.srcOffset.z = 0;
17393 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17394 resolveRegion.dstSubresource.mipLevel = 0;
17395 resolveRegion.dstSubresource.baseArrayLayer = 0;
17396 resolveRegion.dstSubresource.layerCount = 1;
17397 resolveRegion.dstOffset.x = 0;
17398 resolveRegion.dstOffset.y = 0;
17399 resolveRegion.dstOffset.z = 0;
17400 resolveRegion.extent.width = 1;
17401 resolveRegion.extent.height = 1;
17402 resolveRegion.extent.depth = 1;
17403 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17404 EndCommandBuffer();
17406 m_errorMonitor->VerifyFound();
17408 vkDestroyImage(m_device->device(), srcImage, NULL);
17409 vkDestroyImage(m_device->device(), dstImage, NULL);
17410 vkFreeMemory(m_device->device(), srcMem, NULL);
17411 vkFreeMemory(m_device->device(), destMem, NULL);
17414 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
17418 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17419 "vkCmdResolveImage called with unmatched source and dest formats.");
17421 ASSERT_NO_FATAL_FAILURE(InitState());
17423 // Create two images of different types and try to copy between them
17426 VkDeviceMemory srcMem;
17427 VkDeviceMemory destMem;
17428 VkMemoryRequirements memReqs;
17430 VkImageCreateInfo image_create_info = {};
17431 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17432 image_create_info.pNext = NULL;
17433 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17434 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17435 image_create_info.extent.width = 32;
17436 image_create_info.extent.height = 1;
17437 image_create_info.extent.depth = 1;
17438 image_create_info.mipLevels = 1;
17439 image_create_info.arrayLayers = 1;
17440 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17441 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17442 // Note: Some implementations expect color attachment usage for any
17443 // multisample surface
17444 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17445 image_create_info.flags = 0;
17447 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17448 ASSERT_VK_SUCCESS(err);
17450 // Set format to something other than source image
17451 image_create_info.format = VK_FORMAT_R32_SFLOAT;
17452 // Note: Some implementations expect color attachment usage for any
17453 // multisample surface
17454 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17455 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17457 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17458 ASSERT_VK_SUCCESS(err);
17461 VkMemoryAllocateInfo memAlloc = {};
17462 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17463 memAlloc.pNext = NULL;
17464 memAlloc.allocationSize = 0;
17465 memAlloc.memoryTypeIndex = 0;
17467 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17468 memAlloc.allocationSize = memReqs.size;
17469 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17471 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17472 ASSERT_VK_SUCCESS(err);
17474 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17475 memAlloc.allocationSize = memReqs.size;
17476 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17478 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17479 ASSERT_VK_SUCCESS(err);
17481 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17482 ASSERT_VK_SUCCESS(err);
17483 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17484 ASSERT_VK_SUCCESS(err);
17486 BeginCommandBuffer();
17487 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17488 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17489 // VK_IMAGE_LAYOUT_GENERAL = 1,
17490 VkImageResolve resolveRegion;
17491 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17492 resolveRegion.srcSubresource.mipLevel = 0;
17493 resolveRegion.srcSubresource.baseArrayLayer = 0;
17494 resolveRegion.srcSubresource.layerCount = 1;
17495 resolveRegion.srcOffset.x = 0;
17496 resolveRegion.srcOffset.y = 0;
17497 resolveRegion.srcOffset.z = 0;
17498 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17499 resolveRegion.dstSubresource.mipLevel = 0;
17500 resolveRegion.dstSubresource.baseArrayLayer = 0;
17501 resolveRegion.dstSubresource.layerCount = 1;
17502 resolveRegion.dstOffset.x = 0;
17503 resolveRegion.dstOffset.y = 0;
17504 resolveRegion.dstOffset.z = 0;
17505 resolveRegion.extent.width = 1;
17506 resolveRegion.extent.height = 1;
17507 resolveRegion.extent.depth = 1;
17508 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17509 EndCommandBuffer();
17511 m_errorMonitor->VerifyFound();
17513 vkDestroyImage(m_device->device(), srcImage, NULL);
17514 vkDestroyImage(m_device->device(), dstImage, NULL);
17515 vkFreeMemory(m_device->device(), srcMem, NULL);
17516 vkFreeMemory(m_device->device(), destMem, NULL);
17519 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
17523 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17524 "vkCmdResolveImage called with unmatched source and dest image types.");
17526 ASSERT_NO_FATAL_FAILURE(InitState());
17528 // Create two images of different types and try to copy between them
17531 VkDeviceMemory srcMem;
17532 VkDeviceMemory destMem;
17533 VkMemoryRequirements memReqs;
17535 VkImageCreateInfo image_create_info = {};
17536 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17537 image_create_info.pNext = NULL;
17538 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17539 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
17540 image_create_info.extent.width = 32;
17541 image_create_info.extent.height = 1;
17542 image_create_info.extent.depth = 1;
17543 image_create_info.mipLevels = 1;
17544 image_create_info.arrayLayers = 1;
17545 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
17546 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17547 // Note: Some implementations expect color attachment usage for any
17548 // multisample surface
17549 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17550 image_create_info.flags = 0;
17552 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
17553 ASSERT_VK_SUCCESS(err);
17555 image_create_info.imageType = VK_IMAGE_TYPE_1D;
17556 // Note: Some implementations expect color attachment usage for any
17557 // multisample surface
17558 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17559 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17561 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
17562 ASSERT_VK_SUCCESS(err);
17565 VkMemoryAllocateInfo memAlloc = {};
17566 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17567 memAlloc.pNext = NULL;
17568 memAlloc.allocationSize = 0;
17569 memAlloc.memoryTypeIndex = 0;
17571 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
17572 memAlloc.allocationSize = memReqs.size;
17573 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17575 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
17576 ASSERT_VK_SUCCESS(err);
17578 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
17579 memAlloc.allocationSize = memReqs.size;
17580 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
17582 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
17583 ASSERT_VK_SUCCESS(err);
17585 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
17586 ASSERT_VK_SUCCESS(err);
17587 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
17588 ASSERT_VK_SUCCESS(err);
17590 BeginCommandBuffer();
17591 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
17592 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
17593 // VK_IMAGE_LAYOUT_GENERAL = 1,
17594 VkImageResolve resolveRegion;
17595 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17596 resolveRegion.srcSubresource.mipLevel = 0;
17597 resolveRegion.srcSubresource.baseArrayLayer = 0;
17598 resolveRegion.srcSubresource.layerCount = 1;
17599 resolveRegion.srcOffset.x = 0;
17600 resolveRegion.srcOffset.y = 0;
17601 resolveRegion.srcOffset.z = 0;
17602 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17603 resolveRegion.dstSubresource.mipLevel = 0;
17604 resolveRegion.dstSubresource.baseArrayLayer = 0;
17605 resolveRegion.dstSubresource.layerCount = 1;
17606 resolveRegion.dstOffset.x = 0;
17607 resolveRegion.dstOffset.y = 0;
17608 resolveRegion.dstOffset.z = 0;
17609 resolveRegion.extent.width = 1;
17610 resolveRegion.extent.height = 1;
17611 resolveRegion.extent.depth = 1;
17612 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
17613 EndCommandBuffer();
17615 m_errorMonitor->VerifyFound();
17617 vkDestroyImage(m_device->device(), srcImage, NULL);
17618 vkDestroyImage(m_device->device(), dstImage, NULL);
17619 vkFreeMemory(m_device->device(), srcMem, NULL);
17620 vkFreeMemory(m_device->device(), destMem, NULL);
17623 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
17624 // Create a single Image descriptor and cause it to first hit an error due
17625 // to using a DS format, then cause it to hit error due to COLOR_BIT not
17627 // The image format check comes 2nd in validation so we trigger it first,
17628 // then when we cause aspect fail next, bad format check will be preempted
17631 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17632 "Combination depth/stencil image formats can have only the ");
17634 ASSERT_NO_FATAL_FAILURE(InitState());
17636 VkDescriptorPoolSize ds_type_count = {};
17637 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17638 ds_type_count.descriptorCount = 1;
17640 VkDescriptorPoolCreateInfo ds_pool_ci = {};
17641 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
17642 ds_pool_ci.pNext = NULL;
17643 ds_pool_ci.maxSets = 1;
17644 ds_pool_ci.poolSizeCount = 1;
17645 ds_pool_ci.pPoolSizes = &ds_type_count;
17647 VkDescriptorPool ds_pool;
17648 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
17649 ASSERT_VK_SUCCESS(err);
17651 VkDescriptorSetLayoutBinding dsl_binding = {};
17652 dsl_binding.binding = 0;
17653 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
17654 dsl_binding.descriptorCount = 1;
17655 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
17656 dsl_binding.pImmutableSamplers = NULL;
17658 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
17659 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
17660 ds_layout_ci.pNext = NULL;
17661 ds_layout_ci.bindingCount = 1;
17662 ds_layout_ci.pBindings = &dsl_binding;
17663 VkDescriptorSetLayout ds_layout;
17664 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
17665 ASSERT_VK_SUCCESS(err);
17667 VkDescriptorSet descriptorSet;
17668 VkDescriptorSetAllocateInfo alloc_info = {};
17669 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
17670 alloc_info.descriptorSetCount = 1;
17671 alloc_info.descriptorPool = ds_pool;
17672 alloc_info.pSetLayouts = &ds_layout;
17673 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
17674 ASSERT_VK_SUCCESS(err);
17677 VkImage image_good;
17678 // One bad format and one good format for Color attachment
17679 const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
17680 const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
17681 const int32_t tex_width = 32;
17682 const int32_t tex_height = 32;
17684 VkImageCreateInfo image_create_info = {};
17685 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17686 image_create_info.pNext = NULL;
17687 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17688 image_create_info.format = tex_format_bad;
17689 image_create_info.extent.width = tex_width;
17690 image_create_info.extent.height = tex_height;
17691 image_create_info.extent.depth = 1;
17692 image_create_info.mipLevels = 1;
17693 image_create_info.arrayLayers = 1;
17694 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17695 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17696 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17697 image_create_info.flags = 0;
17699 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
17700 ASSERT_VK_SUCCESS(err);
17701 image_create_info.format = tex_format_good;
17702 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
17703 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
17704 ASSERT_VK_SUCCESS(err);
17706 VkImageViewCreateInfo image_view_create_info = {};
17707 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17708 image_view_create_info.image = image_bad;
17709 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
17710 image_view_create_info.format = tex_format_bad;
17711 image_view_create_info.subresourceRange.baseArrayLayer = 0;
17712 image_view_create_info.subresourceRange.baseMipLevel = 0;
17713 image_view_create_info.subresourceRange.layerCount = 1;
17714 image_view_create_info.subresourceRange.levelCount = 1;
17715 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17718 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
17720 m_errorMonitor->VerifyFound();
17722 vkDestroyImage(m_device->device(), image_bad, NULL);
17723 vkDestroyImage(m_device->device(), image_good, NULL);
17724 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
17725 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
17728 TEST_F(VkLayerTest, ClearImageErrors) {
17729 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and "
17730 "ClearDepthStencilImage with a color image.");
17732 ASSERT_NO_FATAL_FAILURE(InitState());
17733 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17735 // Renderpass is started here so end it as Clear cmds can't be in renderpass
17736 BeginCommandBuffer();
17737 m_commandBuffer->EndRenderPass();
17740 VkClearColorValue clear_color;
17741 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
17742 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
17743 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
17744 const int32_t img_width = 32;
17745 const int32_t img_height = 32;
17746 VkImageCreateInfo image_create_info = {};
17747 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17748 image_create_info.pNext = NULL;
17749 image_create_info.imageType = VK_IMAGE_TYPE_2D;
17750 image_create_info.format = color_format;
17751 image_create_info.extent.width = img_width;
17752 image_create_info.extent.height = img_height;
17753 image_create_info.extent.depth = 1;
17754 image_create_info.mipLevels = 1;
17755 image_create_info.arrayLayers = 1;
17756 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17757 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
17758 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
17760 vk_testing::Image color_image;
17761 color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
17763 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
17765 // Depth/Stencil image
17766 VkClearDepthStencilValue clear_value = {0};
17767 reqs = 0; // don't need HOST_VISIBLE DS image
17768 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
17769 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
17770 ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
17771 ds_image_create_info.extent.width = 64;
17772 ds_image_create_info.extent.height = 64;
17773 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17774 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17776 vk_testing::Image ds_image;
17777 ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs);
17779 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
17781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
17783 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17786 m_errorMonitor->VerifyFound();
17788 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with "
17789 "image created without "
17790 "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
17792 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
17795 m_errorMonitor->VerifyFound();
17797 // Call CmdClearDepthStencilImage with color image
17798 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17799 "vkCmdClearDepthStencilImage called without a depth/stencil image.");
17801 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(),
17802 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range);
17804 m_errorMonitor->VerifyFound();
17806 #endif // IMAGE_TESTS
17808 #if defined(ANDROID) && defined(VALIDATION_APK)
17809 static bool initialized = false;
17810 static bool active = false;
17812 // Convert Intents to argv
17813 // Ported from Hologram sample, only difference is flexible key
17814 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
17815 std::vector<std::string> args;
17816 JavaVM &vm = *app.activity->vm;
17818 if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
17821 JNIEnv &env = *p_env;
17822 jobject activity = app.activity->clazz;
17823 jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
17824 jobject intent = env.CallObjectMethod(activity, get_intent_method);
17825 jmethodID get_string_extra_method =
17826 env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
17827 jvalue get_string_extra_args;
17828 get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
17829 jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
17831 std::string args_str;
17833 const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
17834 args_str = extra_utf;
17835 env.ReleaseStringUTFChars(extra_str, extra_utf);
17836 env.DeleteLocalRef(extra_str);
17839 env.DeleteLocalRef(get_string_extra_args.l);
17840 env.DeleteLocalRef(intent);
17841 vm.DetachCurrentThread();
17844 std::stringstream ss(args_str);
17846 while (std::getline(ss, arg, ' ')) {
17848 args.push_back(arg);
17854 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
17856 static void processCommand(struct android_app *app, int32_t cmd) {
17858 case APP_CMD_INIT_WINDOW: {
17860 initialized = true;
17864 case APP_CMD_GAINED_FOCUS: {
17868 case APP_CMD_LOST_FOCUS: {
17875 void android_main(struct android_app *app) {
17878 const char *appTag = "VulkanLayerValidationTests";
17880 int vulkanSupport = InitVulkan();
17881 if (vulkanSupport == 0) {
17882 __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
17886 app->onAppCmd = processCommand;
17887 app->onInputEvent = processInput;
17891 struct android_poll_source *source;
17892 while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
17894 source->process(app, source);
17897 if (app->destroyRequested != 0) {
17898 VkTestFramework::Finish();
17903 if (initialized && active) {
17904 // Use the following key to send arguments to gtest, i.e.
17905 // --es args "--gtest_filter=-VkLayerTest.foo"
17906 const char key[] = "args";
17907 std::vector<std::string> args = get_args(*app, key);
17909 std::string filter = "";
17910 if (args.size() > 0) {
17911 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
17914 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
17918 char *argv[] = {(char *)"foo", (char *)filter.c_str()};
17919 __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
17921 // Route output to files until we can override the gtest output
17922 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
17923 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
17925 ::testing::InitGoogleTest(&argc, argv);
17926 VkTestFramework::InitArgs(&argc, argv);
17927 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17929 int result = RUN_ALL_TESTS();
17932 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
17934 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
17937 VkTestFramework::Finish();
17942 ANativeActivity_finish(app->activity);
17950 int main(int argc, char **argv) {
17954 int vulkanSupport = InitVulkan();
17955 if (vulkanSupport == 0)
17959 ::testing::InitGoogleTest(&argc, argv);
17960 VkTestFramework::InitArgs(&argc, argv);
17962 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
17964 result = RUN_ALL_TESTS();
17966 VkTestFramework::Finish();