| /* |
| * Copyright (c) 2015-2023 The Khronos Group Inc. |
| * Copyright (c) 2015-2023 Valve Corporation |
| * Copyright (c) 2015-2023 LunarG, Inc. |
| * Copyright (c) 2015-2023 Google, Inc. |
| * Modifications Copyright (C) 2020-2022 Advanced Micro Devices, Inc. All rights reserved. |
| * Modifications Copyright (C) 2021 ARM, Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include "utils/cast_utils.h" |
| #include "../framework/layer_validation_tests.h" |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentIndexOutOfRange) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| // There are no attachments, but refer to attachment 0. |
| VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| }; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 0u, nullptr, 1u, subpasses, 0u, nullptr); |
| |
| // "... must be less than the total number of attachments ..." |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, true, "VUID-VkRenderPassCreateInfo-attachment-00834", |
| "VUID-VkRenderPassCreateInfo2-attachment-03051"); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentReadOnlyButCleared) { |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| const bool maintenance2Supported = IsExtensionsEnabled(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentDescription description = {0, |
| ds_format, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_GENERAL, |
| VK_IMAGE_LAYOUT_GENERAL}; |
| |
| VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_GENERAL}; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, |
| nullptr}; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 1u, &description, 1u, &subpass, 0u, nullptr); |
| |
| // Test both cases when rp2 is not supported |
| |
| // Set loadOp to clear |
| description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| |
| depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pAttachments-00836", |
| "VUID-VkRenderPassCreateInfo2-pAttachments-02522"); |
| |
| if (maintenance2Supported == true) { |
| depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkRenderPassCreateInfo-pAttachments-01566", "VUID-VkRenderPassCreateInfo2-pAttachments-02522"); |
| } |
| |
| description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; // reset |
| |
| // Set stencilLoadOp to clear |
| description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| |
| depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pAttachments-02511", |
| "VUID-VkRenderPassCreateInfo2-pAttachments-02523"); |
| |
| if (maintenance2Supported == true) { |
| depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkRenderPassCreateInfo-pAttachments-01567", "VUID-VkRenderPassCreateInfo2-pAttachments-02523"); |
| } |
| |
| description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; // reset |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentMismatchingLayoutsColor) { |
| TEST_DESCRIPTION("Attachment is used simultaneously as two color attachments with different layouts."); |
| |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference refs[] = { |
| {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {0, VK_IMAGE_LAYOUT_GENERAL}, |
| }; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, refs, nullptr, nullptr, 0, nullptr}, |
| }; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 1u, attach, 1u, subpasses, 0u, nullptr); |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, true, |
| "subpass 0 already uses attachment 0 with a different image layout", |
| "subpass 0 already uses attachment 0 with a different image layout"); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentDescriptionInvalidFinalLayout) { |
| TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED"); |
| |
| AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| auto separate_depth_stencil_layouts_features = LvlInitStruct<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(); |
| auto features2 = GetPhysicalDeviceFeatures2(separate_depth_stencil_layouts_features); |
| separate_depth_stencil_layouts_features.separateDepthStencilLayouts = VK_FALSE; |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2)); |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| VkAttachmentReference attach_ref = {}; |
| attach_ref.attachment = 0; |
| attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach_ref; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-finalLayout-00843", |
| "VUID-VkAttachmentDescription2-finalLayout-00843"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-finalLayout-00843", |
| "VUID-VkAttachmentDescription2-finalLayout-00843"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto depth_format = FindSupportedDepthOnlyFormat(gpu()); |
| auto depth_stencil_format = FindSupportedDepthStencilFormat(gpu()); |
| auto stencil_format = FindSupportedStencilOnlyFormat(gpu()); |
| if (stencil_format == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "Couldn't find a stencil only image format"; |
| } |
| |
| if (separate_depth_stencil_layouts_features.separateDepthStencilLayouts) { |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03286", |
| "VUID-VkAttachmentDescription2-format-03286"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03286", |
| "VUID-VkAttachmentDescription2-format-03286"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03286", |
| "VUID-VkAttachmentDescription2-format-03286"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03286", |
| "VUID-VkAttachmentDescription2-format-03286"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03287", |
| "VUID-VkAttachmentDescription2-format-03287"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03287", |
| "VUID-VkAttachmentDescription2-format-03287"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03287", |
| "VUID-VkAttachmentDescription2-format-03287"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03287", |
| "VUID-VkAttachmentDescription2-format-03287"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| if (depth_format) { |
| attach_desc.format = depth_format; |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03290", "VUID-VkAttachmentDescription2-format-03290"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03290", "VUID-VkAttachmentDescription2-format-03290"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03291", "VUID-VkAttachmentDescription2-format-03291"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03291", "VUID-VkAttachmentDescription2-format-03291"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| } |
| |
| if (stencil_format) { |
| attach_desc.format = stencil_format; |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03292", "VUID-VkAttachmentDescription2-format-06247"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03292", "VUID-VkAttachmentDescription2-format-06247"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03293", "VUID-VkAttachmentDescription2-format-06248"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-format-03293", "VUID-VkAttachmentDescription2-format-06248"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| } |
| |
| if (rp2Supported && depth_stencil_format) { |
| attach_desc.format = depth_stencil_format; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| |
| auto attachment_description_stencil_layout = LvlInitStruct<VkAttachmentDescriptionStencilLayoutKHR>(); |
| attachment_description_stencil_layout.stencilInitialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachment_description_stencil_layout.stencilFinalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| safe_VkRenderPassCreateInfo2 rpci2 = ConvertVkRenderPassCreateInfoToV2KHR(rpci); |
| rpci2.pAttachments[0].pNext = &attachment_description_stencil_layout; |
| |
| VkImageLayout forbidden_layouts[] = { |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, |
| VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, |
| }; |
| auto forbidden_layouts_array_size = sizeof(forbidden_layouts) / sizeof(forbidden_layouts[0]); |
| |
| for (size_t i = 0; i < forbidden_layouts_array_size; ++i) { |
| attachment_description_stencil_layout.stencilInitialLayout = forbidden_layouts[i]; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentDescriptionStencilLayout-stencilInitialLayout-03308"); |
| } |
| attachment_description_stencil_layout.stencilInitialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| for (size_t i = 0; i < forbidden_layouts_array_size; ++i) { |
| attachment_description_stencil_layout.stencilFinalLayout = forbidden_layouts[i]; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03309"); |
| } |
| attachment_description_stencil_layout.stencilFinalLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03310"); |
| attachment_description_stencil_layout.stencilFinalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03310"); |
| |
| rpci2.pAttachments[0].pNext = nullptr; |
| } |
| } else { |
| if (depth_format) { |
| attach_desc.format = depth_format; |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03284"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03284"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03285"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03285"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| } |
| if (stencil_format) { |
| attach_desc.format = stencil_format; |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03284"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03284"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03285"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285", |
| "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03285"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| } |
| } |
| |
| // Test invalid layouts for color formats |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03280", |
| "VUID-VkAttachmentDescription2-format-03280"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03282", |
| "VUID-VkAttachmentDescription2-format-03282"); |
| |
| // invalid formats without synchronization2 |
| { |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-synchronization2-06908", |
| "VUID-VkAttachmentDescription2-synchronization2-06908"); |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-synchronization2-06908", |
| "VUID-VkAttachmentDescription2-synchronization2-06908"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-synchronization2-06909", |
| "VUID-VkAttachmentDescription2-synchronization2-06909"); |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkAttachmentDescription-synchronization2-06909", |
| "VUID-VkAttachmentDescription2-synchronization2-06909"); |
| |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| } |
| |
| // Test invalid layouts for depth/stencil format |
| if (depth_stencil_format) { |
| attach_desc.format = depth_stencil_format; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03281", |
| "VUID-VkAttachmentDescription2-format-03281"); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-03283", |
| "VUID-VkAttachmentDescription2-format-03283"); |
| } |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentsMisc) { |
| TEST_DESCRIPTION( |
| "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage " |
| "conditions."); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| std::vector<VkAttachmentDescription> attachments = { |
| // input attachments |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, |
| // color attachments |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // depth attachment |
| {0, ds_format, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, |
| // resolve attachment |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // preserve attachments |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // depth non-resolve attachment |
| {0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, |
| }; |
| |
| std::vector<VkAttachmentReference> input = { |
| {0, VK_IMAGE_LAYOUT_GENERAL}, |
| }; |
| std::vector<VkAttachmentReference> color = { |
| {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; |
| std::vector<VkAttachmentReference> resolve = { |
| {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| std::vector<uint32_t> preserve = {5}; |
| std::vector<VkAttachmentReference> depth_1bit = { |
| {6, VK_IMAGE_LAYOUT_GENERAL}, |
| {6, VK_IMAGE_LAYOUT_GENERAL}, |
| }; |
| |
| VkSubpassDescription subpass = {0, |
| VK_PIPELINE_BIND_POINT_GRAPHICS, |
| size32(input), |
| input.data(), |
| size32(color), |
| color.data(), |
| resolve.data(), |
| &depth, |
| size32(preserve), |
| preserve.data()}; |
| |
| auto rpci = |
| LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, size32(attachments), attachments.data(), 1u, &subpass, 0u, nullptr); |
| |
| // Test too many color attachments |
| const uint32_t max_color_attachments = m_device->props.limits.maxColorAttachments; |
| const uint32_t too_big_max_attachments = 65536 + 1; // let's say this is too much to allocate |
| if (max_color_attachments >= too_big_max_attachments) { |
| printf("VkPhysicalDeviceLimits::maxColorAttachments is too large to practically test against -- skipping part of test.\n"); |
| } else { |
| std::vector<VkAttachmentReference> too_many_colors(max_color_attachments + 1, color[0]); |
| VkSubpassDescription test_subpass = subpass; |
| test_subpass.colorAttachmentCount = size32(too_many_colors); |
| test_subpass.pColorAttachments = too_many_colors.data(); |
| test_subpass.pResolveAttachments = NULL; |
| VkRenderPassCreateInfo test_rpci = rpci; |
| test_rpci.pSubpasses = &test_subpass; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &test_rpci, rp2Supported, |
| "VUID-VkSubpassDescription-colorAttachmentCount-00845", |
| "VUID-VkSubpassDescription2-colorAttachmentCount-03063"); |
| } |
| |
| // Test sample count mismatch between color buffers |
| attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT; |
| depth.attachment = VK_ATTACHMENT_UNUSED; // Avoids triggering 01418 |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pColorAttachments-06868", |
| "VUID-VkSubpassDescription2-multisampledRenderToSingleSampled-06872"); |
| |
| depth.attachment = 3; |
| attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; |
| |
| // Test sample count mismatch between color buffers and depth buffer |
| attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT; |
| subpass.colorAttachmentCount = 1; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pDepthStencilAttachment-01418", |
| "VUID-VkSubpassDescription2-multisampledRenderToSingleSampled-06872"); |
| |
| attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; |
| subpass.colorAttachmentCount = size32(color); |
| |
| // Test resolve attachment with UNUSED color attachment |
| color[0].attachment = VK_ATTACHMENT_UNUSED; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pResolveAttachments-00847", |
| "VUID-VkSubpassDescription2-pResolveAttachments-03065"); |
| |
| color[0].attachment = 1; |
| |
| // Test resolve from a single-sampled color attachment |
| attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; |
| subpass.colorAttachmentCount = 1; // avoid mismatch (00337), and avoid double report |
| subpass.pDepthStencilAttachment = nullptr; // avoid mismatch (01418) |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pResolveAttachments-00848", |
| "VUID-VkSubpassDescription2-pResolveAttachments-03066"); |
| |
| attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; |
| subpass.colorAttachmentCount = size32(color); |
| subpass.pDepthStencilAttachment = &depth; |
| |
| // Test resolve to a multi-sampled resolve attachment |
| attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pResolveAttachments-00849", |
| "VUID-VkSubpassDescription2-pResolveAttachments-03067"); |
| |
| attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; |
| |
| // Test with color/resolve format mismatch |
| attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pResolveAttachments-00850", |
| "VUID-VkSubpassDescription2-pResolveAttachments-03068"); |
| |
| attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format; |
| |
| // Test for UNUSED preserve attachments |
| preserve[0] = VK_ATTACHMENT_UNUSED; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-attachment-00853", |
| "VUID-VkSubpassDescription2-attachment-03073"); |
| |
| preserve[0] = 5; |
| // Test for preserve attachments used elsewhere in the subpass |
| color[0].attachment = preserve[0]; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pPreserveAttachments-00854", |
| "VUID-VkSubpassDescription2-pPreserveAttachments-03074"); |
| |
| color[0].attachment = 1; |
| input[0].attachment = 0; |
| input[0].layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| // Test for attachment used first as input with loadOp=CLEAR |
| { |
| std::vector<VkSubpassDescription> subpasses = {subpass, subpass, subpass}; |
| subpasses[0].inputAttachmentCount = 0; |
| subpasses[1].inputAttachmentCount = 0; |
| attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| auto rpci_multipass = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, size32(attachments), attachments.data(), |
| size32(subpasses), subpasses.data(), 0u, nullptr); |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci_multipass, rp2Supported, |
| "VUID-VkSubpassDescription-loadOp-00846", "VUID-VkSubpassDescription2-loadOp-03064"); |
| |
| attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| } |
| |
| // Test for depthStencil and color pointing to same attachment |
| { |
| // Both use same VkAttachmentReference |
| VkSubpassDescription subpass_same = { |
| 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, depth_1bit.data(), nullptr, depth_1bit.data(), 0, nullptr}; |
| |
| VkRenderPassCreateInfo rpci_same = rpci; |
| rpci_same.pSubpasses = &subpass_same; |
| |
| // only test rp1 so can ignore the expected 2nd error |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription-pColorAttachments-02648"); |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci_same, false, |
| "VUID-VkSubpassDescription-pDepthStencilAttachment-04438", nullptr); |
| |
| if (rp2Supported) { |
| safe_VkRenderPassCreateInfo2 create_info2 = ConvertVkRenderPassCreateInfoToV2KHR(rpci_same); |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription2-pColorAttachments-02898"); |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), create_info2.ptr(), |
| "VUID-VkSubpassDescription2-pDepthStencilAttachment-04440"); |
| } |
| |
| // Same test but use 2 different VkAttachmentReference to point to same attachment |
| subpass_same.pDepthStencilAttachment = &depth_1bit.data()[1]; |
| |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription-pColorAttachments-02648"); |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci_same, false, |
| "VUID-VkSubpassDescription-pDepthStencilAttachment-04438", nullptr); |
| |
| if (rp2Supported) { |
| safe_VkRenderPassCreateInfo2 create_info2 = ConvertVkRenderPassCreateInfoToV2KHR(rpci_same); |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription2-pColorAttachments-02898"); |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), create_info2.ptr(), |
| "VUID-VkSubpassDescription2-pDepthStencilAttachment-04440"); |
| } |
| } |
| } |
| |
| TEST_F(VkLayerTest, InvalidRenderPassCreateRenderPassShaderResolveQCOM) { |
| TEST_DESCRIPTION("Ensure RenderPass create meets the requirements for QCOM_render_pass_shader_resolve"); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| std::vector<VkAttachmentDescription> attachments = { |
| // input attachments |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, |
| // color attachments |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // depth attachment |
| {0, ds_format, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, |
| // resolve attachment |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| |
| std::vector<VkAttachmentReference> input = { |
| {0, VK_IMAGE_LAYOUT_GENERAL}, |
| }; |
| std::vector<VkAttachmentReference> color = { |
| {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; |
| |
| std::vector<VkAttachmentReference> resolve = { |
| {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| |
| VkSubpassDescription subpass = { |
| 0, VK_PIPELINE_BIND_POINT_GRAPHICS, size32(input), input.data(), size32(color), color.data(), nullptr, &depth, 0, nullptr}; |
| |
| std::vector<VkSubpassDependency> dependency = { |
| {0, 1, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_ACCESS_MEMORY_WRITE_BIT, |
| VK_ACCESS_MEMORY_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT}, |
| }; |
| |
| auto rpci = |
| LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, size32(attachments), attachments.data(), 1u, &subpass, 0u, nullptr); |
| |
| // Create a resolve subpass where the pResolveattachments are not VK_ATTACHMENT_UNUSED |
| VkSubpassDescription test_subpass = subpass; |
| test_subpass.pResolveAttachments = resolve.data(); |
| test_subpass.flags = VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM; |
| VkRenderPassCreateInfo test_rpci = rpci; |
| test_rpci.pSubpasses = &test_subpass; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &test_rpci, rp2Supported, "VUID-VkSubpassDescription-flags-03341", |
| "VUID-VkRenderPassCreateInfo2-flags-04907"); |
| |
| // Create a resolve subpass which is not the last subpass in the subpass dependency chain. |
| { |
| VkSubpassDescription subpasses[2] = {subpass, subpass}; |
| subpasses[0].pResolveAttachments = nullptr; |
| subpasses[0].flags = VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM; |
| subpasses[1].pResolveAttachments = nullptr; |
| subpasses[1].flags = 0; |
| |
| auto test2_rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, size32(attachments), attachments.data(), 2u, subpasses, |
| size32(dependency), dependency.data()); |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &test2_rpci, rp2Supported, "VUID-VkSubpassDescription-flags-03343", |
| "VUID-VkRenderPassCreateInfo2-flags-04909"); |
| } |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentReferenceInvalidLayout) { |
| TEST_DESCRIPTION("Attachment reference uses PREINITIALIZED or UNDEFINED layouts"); |
| |
| AddRequiredExtensions(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| auto separate_depth_stencil_layouts_features = LvlInitStruct<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(); |
| auto features2 = GetPhysicalDeviceFeatures2(separate_depth_stencil_layouts_features); |
| separate_depth_stencil_layouts_features.separateDepthStencilLayouts = VK_FALSE; |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2)); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference refs[] = { |
| {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, // color |
| {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, // depth stencil |
| }; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr}, |
| }; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 2u, attach, 1u, subpasses, 0u, nullptr); |
| |
| // Use UNDEFINED layout |
| refs[0].layout = VK_IMAGE_LAYOUT_UNDEFINED; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentReference-layout-03077", |
| "VUID-VkAttachmentReference2-layout-03077"); |
| |
| // Use PREINITIALIZED layout |
| refs[0].layout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentReference-layout-03077", |
| "VUID-VkAttachmentReference2-layout-03077"); |
| |
| if (rp2Supported) { |
| safe_VkRenderPassCreateInfo2 rpci2 = ConvertVkRenderPassCreateInfoToV2KHR(rpci); |
| |
| // set valid values to start |
| rpci2.pSubpasses[0].pColorAttachments[0].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| rpci2.pSubpasses[0].pColorAttachments[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| |
| if (separate_depth_stencil_layouts_features.separateDepthStencilLayouts) { |
| // Set a valid VkAttachmentReferenceStencilLayout since the feature bit is set |
| auto attachment_reference_stencil_layout = LvlInitStruct<VkAttachmentReferenceStencilLayout>(); |
| attachment_reference_stencil_layout.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->pNext = &attachment_reference_stencil_layout; |
| |
| // reset to valid layout |
| // The following tests originally were negative tests until it was noticed that the aspectMask only matters for input |
| // attachments. These tests were converted into positive tests to catch regression |
| rpci2.pSubpasses[0].pColorAttachments[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| { |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; |
| |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| } |
| { |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| } |
| { |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; |
| |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| PositiveTestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr()); |
| } |
| |
| rpci2.pAttachments[1].format = ds_format; // reset |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; // reset |
| |
| VkImageLayout forbidden_layouts[] = {VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, |
| VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, |
| VK_IMAGE_LAYOUT_PRESENT_SRC_KHR}; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| for (size_t i = 0; i < (sizeof(forbidden_layouts) / sizeof(forbidden_layouts[0])); ++i) { |
| attachment_reference_stencil_layout.stencilLayout = forbidden_layouts[i]; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentReferenceStencilLayout-stencilLayout-03318"); |
| } |
| |
| attachment_reference_stencil_layout.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| |
| auto attachment_description_stencil_layout = LvlInitStruct<VkAttachmentDescriptionStencilLayoutKHR>(); |
| attachment_description_stencil_layout.stencilInitialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| attachment_description_stencil_layout.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| |
| rpci2.pAttachments[1].pNext = &attachment_description_stencil_layout; |
| |
| rpci2.pAttachments[1].initialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| rpci2.pAttachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), "VUID-VkAttachmentDescription2-format-06906"); |
| |
| rpci2.pAttachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; |
| rpci2.pAttachments[1].finalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), "VUID-VkAttachmentDescription2-format-06907"); |
| |
| rpci2.pAttachments[1].pNext = nullptr; |
| |
| rpci2.pAttachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; |
| rpci2.pAttachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), "VUID-VkAttachmentDescription2-format-06249"); |
| |
| rpci2.pAttachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| rpci2.pAttachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), "VUID-VkAttachmentDescription2-format-06250"); |
| |
| rpci2.pSubpasses[0].pDepthStencilAttachment->pNext = nullptr; |
| } else { |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentReference2-separateDepthStencilLayouts-03313"); |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentReference2-separateDepthStencilLayouts-03313"); |
| |
| rpci2.pSubpasses[0].pDepthStencilAttachment->aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentReference2-separateDepthStencilLayouts-03313"); |
| rpci2.pSubpasses[0].pDepthStencilAttachment->layout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPass2KHRCreate(m_errorMonitor, m_device->device(), rpci2.ptr(), |
| "VUID-VkAttachmentReference2-separateDepthStencilLayouts-03313"); |
| } |
| } |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateAttachmentReferenceInvalidSync2Layout) { |
| TEST_DESCRIPTION("Attachment reference uses sync2 and ATTACHMENT_OPTIMAL_KHR or READ_ONLY_OPTIMAL_KHR layouts"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor)); |
| if (DeviceValidationVersion() < VK_API_VERSION_1_3) { |
| GTEST_SKIP() << "At least Vulkan version 1.3 is required"; |
| } |
| |
| // synchronization2 not enabled |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| {0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference refs[] = { |
| {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, // color |
| {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, // depth stencil |
| }; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr}, |
| }; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 2u, attach, 1u, subpasses, 0u, nullptr); |
| |
| // Use ATTACHMENT_OPTIMAL_KHR layout |
| refs[0].layout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, true, "VUID-VkAttachmentReference-synchronization2-06910", |
| "VUID-VkAttachmentReference2-synchronization2-06910"); |
| |
| // Use READ_ONLY_OPTIMAL_KHR layout |
| refs[0].layout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR; |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, true, "VUID-VkAttachmentReference-synchronization2-06910", |
| "VUID-VkAttachmentReference2-synchronization2-06910"); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassCreateInvalidMixedAttachmentSamplesAMD) { |
| TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments."); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| std::vector<VkAttachmentDescription> attachments; |
| |
| { |
| VkAttachmentDescription att = {}; |
| att.format = VK_FORMAT_R8G8B8A8_UNORM; |
| att.samples = VK_SAMPLE_COUNT_1_BIT; |
| att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| attachments.push_back(att); |
| |
| att.format = VK_FORMAT_D16_UNORM; |
| att.samples = VK_SAMPLE_COUNT_4_BIT; |
| att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; |
| att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| |
| attachments.push_back(att); |
| } |
| |
| VkAttachmentReference color_ref = {}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference depth_ref = {}; |
| depth_ref.attachment = 1; |
| depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &color_ref; |
| subpass.pDepthStencilAttachment = &depth_ref; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.attachmentCount = attachments.size(); |
| rpci.pAttachments = attachments.data(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| |
| { |
| // creating and destroying a RenderPass1 should work; |
| vk_testing::RenderPass(*m_device, rpci); |
| } |
| |
| // Expect an error message for invalid sample counts |
| attachments[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| |
| TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, |
| "VUID-VkSubpassDescription-pColorAttachments-01506", "VUID-VkSubpassDescription2-pColorAttachments-03070"); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginInvalidRenderArea) { |
| TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| const bool device_group_supported = IsExtensionsEnabled(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| if (IsPlatform(kShieldTVb)) { |
| GTEST_SKIP() << "ShieldTV reports api version 1.1, but does not list VK_KHR_device_group"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA |
| m_renderPassBeginInfo.renderArea.extent.width = 257; |
| m_renderPassBeginInfo.renderArea.extent.height = 256; |
| |
| const char *vuid = |
| device_group_supported ? "VUID-VkRenderPassBeginInfo-pNext-02852" : "VUID-VkRenderPassBeginInfo-renderArea-02848"; |
| |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &m_renderPassBeginInfo, rp2Supported, vuid, |
| vuid); |
| |
| m_renderPassBeginInfo.renderArea.offset.x = 1; |
| m_renderPassBeginInfo.renderArea.extent.width = vvl::MaxTypeValue(m_renderPassBeginInfo.renderArea.extent.width) - 1; |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &m_renderPassBeginInfo, rp2Supported, vuid, |
| vuid); |
| |
| m_renderPassBeginInfo.renderArea.offset.x = vvl::MaxTypeValue(m_renderPassBeginInfo.renderArea.offset.x); |
| m_renderPassBeginInfo.renderArea.extent.width = vvl::MaxTypeValue(m_renderPassBeginInfo.renderArea.extent.width); |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &m_renderPassBeginInfo, rp2Supported, vuid, |
| vuid); |
| |
| vuid = device_group_supported ? "VUID-VkRenderPassBeginInfo-pNext-02853" : "VUID-VkRenderPassBeginInfo-renderArea-02849"; |
| m_renderPassBeginInfo.renderArea.offset.x = 0; |
| m_renderPassBeginInfo.renderArea.extent.width = 256; |
| m_renderPassBeginInfo.renderArea.offset.y = 1; |
| m_renderPassBeginInfo.renderArea.extent.height = vvl::MaxTypeValue(m_renderPassBeginInfo.renderArea.extent.height) - 1; |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &m_renderPassBeginInfo, rp2Supported, vuid, |
| vuid); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginWithinRenderPass) { |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr; |
| if (rp2Supported) { |
| vkCmdBeginRenderPass2KHR = |
| (PFN_vkCmdBeginRenderPass2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR"); |
| } |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // Bind a BeginRenderPass within an active RenderPass |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); |
| |
| // Just use a dummy Renderpass |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginRenderPass-renderpass"); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| if (rp2Supported) { |
| auto subpassBeginInfo = LvlInitStruct<VkSubpassBeginInfoKHR>(nullptr, VK_SUBPASS_CONTENTS_INLINE); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginRenderPass2-renderpass"); |
| vkCmdBeginRenderPass2KHR(m_commandBuffer->handle(), &m_renderPassBeginInfo, &subpassBeginInfo); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginIncompatibleFramebufferRenderPass) { |
| TEST_DESCRIPTION("Test that renderpass begin is compatible with the framebuffer renderpass "); |
| |
| ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| |
| // Create a depth stencil image view |
| VkImageObj image(m_device); |
| |
| image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); |
| ASSERT_TRUE(image.initialized()); |
| |
| auto dsvci = LvlInitStruct<VkImageViewCreateInfo>(); |
| dsvci.image = image.handle(); |
| dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| dsvci.format = VK_FORMAT_D16_UNORM; |
| dsvci.subresourceRange.layerCount = 1; |
| dsvci.subresourceRange.baseMipLevel = 0; |
| dsvci.subresourceRange.levelCount = 1; |
| dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| vk_testing::ImageView dsv(*m_device, dsvci); |
| |
| // Create a renderPass with a single attachment that uses loadOp CLEAR |
| VkAttachmentDescription description = {0, |
| VK_FORMAT_D16_UNORM, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_LOAD, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_CLEAR, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_GENERAL, |
| VK_IMAGE_LAYOUT_GENERAL}; |
| |
| VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, |
| nullptr}; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 1u, &description, 1u, &subpass, 0u, nullptr); |
| vk_testing::RenderPass rp1(*m_device, rpci); |
| |
| subpass.pDepthStencilAttachment = nullptr; |
| vk_testing::RenderPass rp2(*m_device, rpci); |
| |
| // Create a framebuffer |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, rp1.handle(), 1u, &dsv.handle(), 128u, 128u, 1u); |
| vk_testing::Framebuffer fb(*m_device, fbci); |
| |
| auto rp_begin = |
| LvlInitStruct<VkRenderPassBeginInfo>(nullptr, rp2.handle(), fb.handle(), VkRect2D{{0, 0}, {128u, 128u}}, 0u, nullptr); |
| |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false, |
| "VUID-VkRenderPassBeginInfo-renderPass-00904", nullptr); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginLayoutsFramebufferImageUsageMismatches) { |
| TEST_DESCRIPTION( |
| "Test that renderpass initial/final layouts match up with the usage bits set for each attachment of the framebuffer"); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| const bool feedback_loop_layout = IsExtensionsEnabled(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME); |
| const bool maintenance2Supported = IsExtensionsEnabled(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| if (feedback_loop_layout) { |
| auto attachment_feedback_loop_layout_features = LvlInitStruct<VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT>(); |
| auto features2 = GetPhysicalDeviceFeatures2(attachment_feedback_loop_layout_features); |
| attachment_feedback_loop_layout_features.attachmentFeedbackLoopLayout = true; |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| } else { |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| } |
| |
| // Create an input attachment view |
| VkImageObj iai(m_device); |
| |
| iai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); |
| ASSERT_TRUE(iai.initialized()); |
| |
| auto iavci = LvlInitStruct<VkImageViewCreateInfo>(); |
| iavci.image = iai.handle(); |
| iavci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| iavci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| iavci.subresourceRange.layerCount = 1; |
| iavci.subresourceRange.baseMipLevel = 0; |
| iavci.subresourceRange.levelCount = 1; |
| iavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk_testing::ImageView iav(*m_device, iavci); |
| |
| // Create an input depth attachment view |
| VkImageObj iadi(m_device); |
| |
| VkFormat dformat = FindSupportedDepthStencilFormat(gpu()); |
| iadi.InitNoLayout(128, 128, 1, dformat, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); |
| ASSERT_TRUE(iadi.initialized()); |
| |
| VkImageView iadv = iadi.targetView(dformat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1); |
| |
| // Create a color attachment view |
| VkImageObj cai(m_device); |
| |
| cai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); |
| ASSERT_TRUE(cai.initialized()); |
| |
| auto cavci = LvlInitStruct<VkImageViewCreateInfo>(); |
| cavci.image = cai.handle(); |
| cavci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| cavci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| cavci.subresourceRange.layerCount = 1; |
| cavci.subresourceRange.baseMipLevel = 0; |
| cavci.subresourceRange.levelCount = 1; |
| cavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk_testing::ImageView cav(*m_device, cavci); |
| |
| // Create a renderPass with those attachments |
| VkAttachmentDescription descriptions[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, |
| {1, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}}; |
| |
| VkAttachmentReference input_ref = {0, VK_IMAGE_LAYOUT_GENERAL}; |
| VkAttachmentReference color_ref = {1, VK_IMAGE_LAYOUT_GENERAL}; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input_ref, 1, &color_ref, nullptr, nullptr, 0, nullptr}; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 2u, descriptions, 1u, &subpass, 0u, nullptr); |
| |
| // Create a framebuffer |
| |
| VkImageView views[] = {iav.handle(), cav.handle()}; |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, VK_NULL_HANDLE, 2u, views, 128u, 128u, 1u); |
| |
| VkClearValue clearValues[2]; |
| clearValues[0].color = {{0, 0, 0, 0}}; |
| clearValues[1].color = {{0, 0, 0, 0}}; |
| auto rp_begin = LvlInitStruct<VkRenderPassBeginInfo>(nullptr, VK_NULL_HANDLE, VK_NULL_HANDLE, VkRect2D{{0, 0}, {128u, 128u}}, |
| 2u, clearValues); |
| |
| auto test_layout_helper = [this, &rpci, &rp_begin, rp2Supported, &fbci](const char *rp1_vuid, const char *rp2_vuid) { |
| vk_testing::RenderPass rp_invalid(*m_device, rpci); |
| fbci.renderPass = rp_invalid.handle(); |
| vk_testing::Framebuffer fb_invalid(*m_device, fbci); |
| rp_begin.renderPass = rp_invalid.handle(); |
| rp_begin.framebuffer = fb_invalid.handle(); |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported, rp1_vuid, |
| rp2_vuid); |
| }; |
| |
| // Initial layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but attachment doesn't support IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-00895", "VUID-vkCmdBeginRenderPass2-initialLayout-03094"); |
| |
| // Initial layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
| // / VK_IMAGE_USAGE_SAMPLED_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| descriptions[1].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-00897", "VUID-vkCmdBeginRenderPass2-initialLayout-03097"); |
| |
| descriptions[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-00898", "VUID-vkCmdBeginRenderPass2-initialLayout-03098"); |
| |
| // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-00899", "VUID-vkCmdBeginRenderPass2-initialLayout-03099"); |
| |
| // Change to depth views since we are changing format |
| descriptions[0].format = dformat; |
| views[0] = iadv; |
| |
| // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support |
| // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| const char *initial_layout_vuid_rp1 = |
| maintenance2Supported ? "VUID-vkCmdBeginRenderPass-initialLayout-01758" : "VUID-vkCmdBeginRenderPass-initialLayout-00896"; |
| test_layout_helper(initial_layout_vuid_rp1, "VUID-vkCmdBeginRenderPass2-initialLayout-03096"); |
| |
| // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support |
| // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| test_layout_helper(initial_layout_vuid_rp1, "VUID-vkCmdBeginRenderPass2-initialLayout-03096"); |
| |
| if (maintenance2Supported || rp2Supported) { |
| // Initial layout is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support |
| // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2-initialLayout-03096"); |
| |
| // Initial layout is VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support |
| // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2-initialLayout-03096"); |
| } |
| |
| if (feedback_loop_layout) { |
| VkImageObj no_fb_loop_attachment(m_device); |
| // No VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
| no_fb_loop_attachment.InitNoLayout( |
| 128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, |
| VK_IMAGE_TILING_OPTIMAL); |
| vk_testing::ImageView image_view_no_fb_loop; |
| auto image_view_ci = no_fb_loop_attachment.TargetViewCI(VK_FORMAT_R8G8B8A8_UNORM); |
| image_view_ci.image = no_fb_loop_attachment.handle(); |
| image_view_no_fb_loop.init(*m_device, image_view_ci); |
| views[0] = image_view_no_fb_loop.handle(); |
| descriptions[0].format = VK_FORMAT_R8G8B8A8_UNORM; |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-07001", "VUID-vkCmdBeginRenderPass2-initialLayout-07003"); |
| |
| descriptions[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| descriptions[0].format = dformat; |
| ; |
| views[0] = iadv; |
| VkImageObj no_usage_sampled_attachment(m_device); |
| // No VK_IMAGE_USAGE_SAMPLED_BIT_EXT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
| no_usage_sampled_attachment.InitNoLayout( |
| 128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT, VK_IMAGE_TILING_OPTIMAL); |
| image_view_ci.image = no_usage_sampled_attachment.handle(); |
| vk_testing::ImageView image_view_no_usage_sampled; |
| image_view_no_usage_sampled.init(*m_device, image_view_ci); |
| descriptions[1].initialLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; |
| views[1] = image_view_no_usage_sampled.handle(); |
| test_layout_helper("VUID-vkCmdBeginRenderPass-initialLayout-07000", "VUID-vkCmdBeginRenderPass2-initialLayout-07002"); |
| } |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginClearOpMismatch) { |
| TEST_DESCRIPTION( |
| "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use " |
| "loadOp VK_ATTACHMENT_LOAD_OP_CLEAR."); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // Create a renderPass with a single attachment that uses loadOp CLEAR |
| VkAttachmentReference attach = {}; |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; |
| // Set loadOp to CLEAR |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| auto rp_begin = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rp_begin.renderPass = renderPass(); |
| rp_begin.framebuffer = framebuffer(); |
| rp_begin.clearValueCount = 0; // Should be 1 |
| |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported, |
| "VUID-VkRenderPassBeginInfo-clearValueCount-00902", "VUID-VkRenderPassBeginInfo-clearValueCount-00902"); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginSampleLocationsInvalidIndicesEXT) { |
| TEST_DESCRIPTION("Test that attachment indices and subpass indices specifed by sample locations structures are valid"); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| |
| PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = |
| (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR"); |
| assert(vkGetPhysicalDeviceProperties2KHR != nullptr); |
| |
| auto sample_locations_props = LvlInitStruct<VkPhysicalDeviceSampleLocationsPropertiesEXT>(); |
| auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&sample_locations_props); |
| vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2); |
| |
| if ((sample_locations_props.sampleLocationSampleCounts & VK_SAMPLE_COUNT_1_BIT) == 0) { |
| GTEST_SKIP() << "VK_SAMPLE_COUNT_1_BIT sampleLocationSampleCounts is not supported"; |
| } |
| |
| // Create a depth stencil image view |
| VkImageObj image(m_device); |
| |
| image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); |
| ASSERT_TRUE(image.initialized()); |
| |
| auto dsvci = LvlInitStruct<VkImageViewCreateInfo>(); |
| dsvci.image = image.handle(); |
| dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| dsvci.format = VK_FORMAT_D16_UNORM; |
| dsvci.subresourceRange.layerCount = 1; |
| dsvci.subresourceRange.baseMipLevel = 0; |
| dsvci.subresourceRange.levelCount = 1; |
| dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| vk_testing::ImageView dsv(*m_device, dsvci); |
| |
| // Create a renderPass with a single attachment that uses loadOp CLEAR |
| VkAttachmentDescription description = {0, |
| VK_FORMAT_D16_UNORM, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_LOAD, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_CLEAR, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_GENERAL, |
| VK_IMAGE_LAYOUT_GENERAL}; |
| |
| VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, |
| nullptr}; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 1u, &description, 1u, &subpass, 0u, nullptr); |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| // Create a framebuffer |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, rp.handle(), 1u, &dsv.handle(), 128u, 128u, 1u); |
| vk_testing::Framebuffer fb(*m_device, fbci); |
| |
| VkSampleLocationEXT sample_location = {0.5, 0.5}; |
| |
| auto sample_locations_info = |
| LvlInitStruct<VkSampleLocationsInfoEXT>(nullptr, VK_SAMPLE_COUNT_1_BIT, VkExtent2D{1u, 1u}, 1u, &sample_location); |
| |
| VkAttachmentSampleLocationsEXT attachment_sample_locations = {0, sample_locations_info}; |
| VkSubpassSampleLocationsEXT subpass_sample_locations = {0, sample_locations_info}; |
| |
| auto rp_sl_begin = LvlInitStruct<VkRenderPassSampleLocationsBeginInfoEXT>(nullptr, 1u, &attachment_sample_locations, 1u, |
| &subpass_sample_locations); |
| |
| auto rp_begin = |
| LvlInitStruct<VkRenderPassBeginInfo>(&rp_sl_begin, rp.handle(), fb.handle(), VkRect2D{{0, 0}, {128u, 128u}}, 0u, nullptr); |
| |
| attachment_sample_locations.attachmentIndex = 1; |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false, |
| "VUID-VkAttachmentSampleLocationsEXT-attachmentIndex-01531", nullptr); |
| attachment_sample_locations.attachmentIndex = 0; |
| |
| subpass_sample_locations.subpassIndex = 1; |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false, |
| "VUID-VkSubpassSampleLocationsEXT-subpassIndex-01532", nullptr); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassDestroyWhileInUse) { |
| TEST_DESCRIPTION("Delete in-use renderPass."); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (IsPlatform(kNexusPlayer)) { |
| GTEST_SKIP() << "This test should not run on Nexus Player"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // Create simple renderpass |
| VkAttachmentReference attach = {}; |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| m_commandBuffer->begin(); |
| auto rpbi = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbi.framebuffer = m_framebuffer; |
| rpbi.renderPass = rp.handle(); |
| m_commandBuffer->BeginRenderPass(rpbi); |
| m_commandBuffer->EndRenderPass(); |
| m_commandBuffer->end(); |
| |
| auto submit_info = LvlInitStruct<VkSubmitInfo>(); |
| submit_info.commandBufferCount = 1; |
| submit_info.pCommandBuffers = &m_commandBuffer->handle(); |
| vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyRenderPass-renderPass-00873"); |
| vk::DestroyRenderPass(m_device->device(), rp.handle(), nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| // Wait for queue to complete so we can safely destroy rp |
| vk::QueueWaitIdle(m_device->m_queue); |
| m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle"); |
| m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?"); |
| } |
| |
| TEST_F(VkLayerTest, FramebufferDepthStencilResolveAttachmentTests) { |
| TEST_DESCRIPTION("Create a framebuffer against a render pass using depth stencil resolve, with mismatched information"); |
| |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported."; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| uint32_t attachmentWidth = 512; |
| uint32_t attachmentHeight = 512; |
| VkFormat attachmentFormat = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentDescription2KHR attachmentDescriptions[2] = {}; |
| // Depth/stencil attachment |
| attachmentDescriptions[0] = LvlInitStruct<VkAttachmentDescription2>(); |
| attachmentDescriptions[0].format = attachmentFormat; |
| attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| // Depth/stencil resolve attachment |
| attachmentDescriptions[1] = LvlInitStruct<VkAttachmentDescription2>(); |
| attachmentDescriptions[1].format = attachmentFormat; |
| attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto depthStencilAttachmentReference = LvlInitStruct<VkAttachmentReference2>(); |
| depthStencilAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilAttachmentReference.attachment = 0; |
| auto depthStencilResolveAttachmentReference = LvlInitStruct<VkAttachmentReference2>(); |
| depthStencilResolveAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilResolveAttachmentReference.attachment = 1; |
| auto subpassDescriptionDepthStencilResolve = LvlInitStruct<VkSubpassDescriptionDepthStencilResolveKHR>(); |
| subpassDescriptionDepthStencilResolve.pDepthStencilResolveAttachment = &depthStencilResolveAttachmentReference; |
| subpassDescriptionDepthStencilResolve.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; |
| subpassDescriptionDepthStencilResolve.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; |
| auto subpassDescription = LvlInitStruct<VkSubpassDescription2>(&subpassDescriptionDepthStencilResolve); |
| subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentReference; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| rpci.attachmentCount = 2; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpassDescription; |
| rpci.pAttachments = attachmentDescriptions; |
| vk_testing::RenderPass rp(*m_device, rpci, true); |
| ASSERT_TRUE(rp.initialized()); |
| |
| // Depth resolve attachment, mismatched image usage |
| // Try creating Framebuffer with images, but with invalid image create usage flags |
| auto image_create_info = LvlInitStruct<VkImageCreateInfo>(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = attachmentFormat; |
| image_create_info.extent.width = attachmentWidth; |
| image_create_info.extent.height = attachmentHeight; |
| image_create_info.extent.depth = 1; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; |
| image_create_info.flags = 0; |
| VkImageObj ds_image(m_device); |
| ds_image.init(&image_create_info); |
| ASSERT_TRUE(ds_image.initialized()); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| VkImageObj ds_resolve_image(m_device); |
| ds_resolve_image.init(&image_create_info); |
| ASSERT_TRUE(ds_resolve_image.initialized()); |
| |
| VkImageView image_views[2]; |
| image_views[0] = ds_image.targetView(attachmentFormat, VK_IMAGE_ASPECT_DEPTH_BIT); |
| image_views[1] = ds_resolve_image.targetView(image_create_info.format, VK_IMAGE_ASPECT_COLOR_BIT); |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fbci.width = attachmentWidth; |
| fbci.height = attachmentHeight; |
| fbci.layers = 1; |
| fbci.renderPass = rp.handle(); |
| fbci.attachmentCount = 2; |
| fbci.pAttachments = image_views; |
| vk_testing::Framebuffer framebuffer; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00880"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-02634"); |
| framebuffer.init(*m_device, fbci); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, FramebufferIncompatible) { |
| TEST_DESCRIPTION( |
| "Bind a secondary command buffer with a framebuffer that does not match the framebuffer for the active renderpass."); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // A renderpass with one color attachment. |
| VkAttachmentDescription attachment = {0, |
| VK_FORMAT_B8G8R8A8_UNORM, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| |
| VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 1u, &attachment, 1u, &subpass, 0u, nullptr); |
| |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| // A compatible framebuffer. |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| ASSERT_TRUE(image.initialized()); |
| |
| auto ivci = |
| LvlInitStruct<VkImageViewCreateInfo>(nullptr, 0u, image.handle(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, |
| VkComponentMapping{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, |
| VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}); |
| vk_testing::ImageView view(*m_device, ivci); |
| |
| auto fci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, rp.handle(), 1u, &view.handle(), 32u, 32u, 1u); |
| vk_testing::Framebuffer fb(*m_device, fci); |
| |
| auto cbai = LvlInitStruct<VkCommandBufferAllocateInfo>(); |
| cbai.commandPool = m_commandPool->handle(); |
| cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; |
| cbai.commandBufferCount = 1; |
| |
| VkCommandBuffer sec_cb; |
| auto err = vk::AllocateCommandBuffers(m_device->device(), &cbai, &sec_cb); |
| ASSERT_VK_SUCCESS(err); |
| auto cbbi = LvlInitStruct<VkCommandBufferBeginInfo>(); |
| auto cbii = LvlInitStruct<VkCommandBufferInheritanceInfo>(); |
| cbii.renderPass = renderPass(); |
| cbii.framebuffer = fb.handle(); |
| cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cbbi.pInheritanceInfo = &cbii; |
| vk::BeginCommandBuffer(sec_cb, &cbbi); |
| vk::EndCommandBuffer(sec_cb); |
| |
| auto cbbi2 = LvlInitStruct<VkCommandBufferBeginInfo>(); |
| vk::BeginCommandBuffer(m_commandBuffer->handle(), &cbbi2); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00099"); |
| vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cb); |
| m_errorMonitor->VerifyFound(); |
| // Cleanup |
| |
| vk::CmdEndRenderPass(m_commandBuffer->handle()); |
| vk::EndCommandBuffer(m_commandBuffer->handle()); |
| } |
| |
| TEST_F(VkLayerTest, NullRenderPass) { |
| // Bind a NULL RenderPass |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdBeginRenderPass: required parameter pRenderPassBegin specified as NULL"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| m_commandBuffer->begin(); |
| // Don't care about RenderPass handle b/c error should be flagged before |
| // that |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), NULL, VK_SUBPASS_CONTENTS_INLINE); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(VkLayerTest, FramebufferCreateErrors) { |
| TEST_DESCRIPTION("VUIDs related to framebuffer creation"); |
| |
| AddOptionalExtensions(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported."; |
| } |
| // TODO - Currently not working on MockICD with Profiles |
| if (IsPlatform(kMockICD)) { |
| GTEST_SKIP() << "Test not supported by MockICD"; |
| } |
| |
| bool imageless_framebuffer_support = IsExtensionsEnabled(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME); |
| |
| bool push_fragment_density_support = IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME) || |
| IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| if (!push_fragment_density_support) { |
| GTEST_SKIP() << "Neither " << VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME << " nor " |
| << VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME << " are supported."; |
| } |
| |
| auto fdm_features = LvlInitStruct<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(); |
| auto features2 = GetPhysicalDeviceFeatures2(fdm_features); |
| if (!fdm_features.fragmentDensityMap) { |
| GTEST_SKIP() << "fragmentDensityMap not supported."; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2)); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| const bool multiview_supported = |
| IsExtensionsEnabled(VK_KHR_MULTIVIEW_EXTENSION_NAME) || (DeviceValidationVersion() >= VK_API_VERSION_1_1); |
| |
| // Create a renderPass with a single color attachment |
| VkAttachmentReference attach = {}; |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.pColorAttachments = &attach; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| |
| VkImageView ivs[2]; |
| ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); |
| ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); |
| |
| auto fb_info = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fb_info.pAttachments = ivs; |
| fb_info.width = 100; |
| fb_info.height = 100; |
| fb_info.layers = 1; |
| VkFramebuffer fb; |
| { |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| fb_info.renderPass = rp.handle(); |
| // Set mis-matching attachmentCount |
| fb_info.attachmentCount = 2; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-attachmentCount-00876"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| // Create a renderPass with a depth-stencil attachment created with |
| // IMAGE_USAGE_COLOR_ATTACHMENT |
| // Add our color attachment to pDepthStencilAttachment |
| subpass.pDepthStencilAttachment = &attach; |
| subpass.pColorAttachments = NULL; |
| |
| vk_testing::RenderPass rp_ds(*m_device, rpci); |
| // Set correct attachment count, but attachment has COLOR usage bit set |
| fb_info.attachmentCount = 1; |
| fb_info.renderPass = rp_ds.handle(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-02633"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| auto image_ci = LvlInitStruct<VkImageCreateInfo>(); |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_ci.extent.width = 256; |
| image_ci.extent.height = 256; |
| image_ci.extent.depth = 1; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| image_ci.flags = 0; |
| VkImageObj image(m_device); |
| image.init(&image_ci); |
| |
| VkImageView view = image.targetView(VK_FORMAT_D16_UNORM); |
| |
| auto fci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, m_renderPass, 1u, &view, 256u, 256u, 1u); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00891"); |
| m_errorMonitor->SetUnexpectedError("VUID-VkFramebufferCreateInfo-pAttachments-00880"); |
| vk::CreateFramebuffer(m_device->device(), &fci, nullptr, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| // Create new renderpass with alternate attachment format from fb |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| subpass.pDepthStencilAttachment = NULL; |
| subpass.pColorAttachments = &attach; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| // Cause error due to mis-matched formats between rp & fb |
| // rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8 |
| fb_info.renderPass = rp.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00880"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| // Create new renderpass with alternate sample count from fb |
| attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_4_BIT; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| // Cause error due to mis-matched sample count between rp & fb |
| fb_info.renderPass = rp.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00881"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| // Create an image with 2 mip levels. |
| VkImageObj image(m_device); |
| image.Init(128, 128, 2, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| ASSERT_TRUE(image.initialized()); |
| |
| // Create a image view with two mip levels. |
| auto ivci = LvlInitStruct<VkImageViewCreateInfo>(); |
| ivci.image = image.handle(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| ivci.subresourceRange.layerCount = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| // Set level count to 2 (only 1 is allowed for FB attachment) |
| ivci.subresourceRange.levelCount = 2; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk_testing::ImageView view(*m_device, ivci); |
| |
| // Re-create renderpass to have matching sample count |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| subpass.colorAttachmentCount = 1; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| |
| subpass.colorAttachmentCount = 0; |
| |
| fb_info.renderPass = rp.handle(); |
| fb_info.pAttachments = &view.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00883"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // Update view to original color buffer and grow FB dimensions too big |
| fb_info.pAttachments = ivs; |
| fb_info.width = 1024; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04533"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| fb_info.width = 256; |
| |
| fb_info.height = 1024; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04534"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| fb_info.height = 256; |
| |
| fb_info.layers = 2; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04535"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| fb_info.layers = 1; |
| |
| if (!push_fragment_density_support || !imageless_framebuffer_support) { |
| printf("VK_EXT_fragment_density_map or VK_KHR_imageless_framebuffer extension not supported, skipping tests\n"); |
| } else { |
| uint32_t attachment_width = 512; |
| uint32_t attachment_height = 512; |
| VkFormat attachment_format = VK_FORMAT_R8G8_UNORM; |
| uint32_t frame_width = 512; |
| uint32_t frame_height = 512; |
| |
| // Create a renderPass with a single color attachment for fragment density map |
| VkAttachmentDescription attach_desc_fragment_density_map = {}; |
| attach_desc_fragment_density_map.format = attachment_format; |
| attach_desc_fragment_density_map.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc_fragment_density_map.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| auto fragment_density_map_create_info = LvlInitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(); |
| fragment_density_map_create_info.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass_fragment_density_map = {}; |
| auto rpci_fragment_density_map = LvlInitStruct<VkRenderPassCreateInfo>(&fragment_density_map_create_info); |
| rpci_fragment_density_map.subpassCount = 1; |
| rpci_fragment_density_map.pSubpasses = &subpass_fragment_density_map; |
| rpci_fragment_density_map.attachmentCount = 1; |
| rpci_fragment_density_map.pAttachments = &attach_desc_fragment_density_map; |
| vk_testing::RenderPass rp_fragment_density_map(*m_device, rpci_fragment_density_map); |
| |
| // Create view attachment |
| auto ivci = LvlInitStruct<VkImageViewCreateInfo>(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = attachment_format; |
| ivci.flags = 0; |
| ivci.subresourceRange.layerCount = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| |
| auto fb_fdm = LvlInitStruct<VkFramebufferAttachmentImageInfoKHR>(); |
| fb_fdm.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| fb_fdm.width = frame_width; |
| fb_fdm.height = frame_height; |
| fb_fdm.layerCount = 1; |
| fb_fdm.viewFormatCount = 1; |
| fb_fdm.pViewFormats = &attachment_format; |
| auto fb_aci_fdm = LvlInitStruct<VkFramebufferAttachmentsCreateInfoKHR>(); |
| fb_aci_fdm.attachmentImageInfoCount = 1; |
| fb_aci_fdm.pAttachmentImageInfos = &fb_fdm; |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(&fb_aci_fdm); |
| fbci.flags = 0; |
| fbci.width = frame_width; |
| fbci.height = frame_height; |
| fbci.layers = 1; |
| fbci.renderPass = rp_fragment_density_map.handle(); |
| fbci.attachmentCount = 1; |
| |
| { |
| // Set small width |
| VkImageObj image2(m_device); |
| image2.Init(16, attachment_height, 1, attachment_format, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT, |
| VK_IMAGE_TILING_LINEAR, 0); |
| ASSERT_TRUE(image2.initialized()); |
| |
| ivci.image = image2.handle(); |
| vk_testing::ImageView view_fragment_density_map(*m_device, ivci); |
| |
| fbci.pAttachments = &view_fragment_density_map.handle(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-02555"); |
| vk::CreateFramebuffer(device(), &fbci, NULL, &fb); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| // Set small height |
| VkImageObj image3(m_device); |
| image3.Init(attachment_width, 16, 1, attachment_format, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT, |
| VK_IMAGE_TILING_LINEAR, 0); |
| ASSERT_TRUE(image3.initialized()); |
| |
| ivci.image = image3.handle(); |
| vk_testing::ImageView view_fragment_density_map(*m_device, ivci); |
| |
| fbci.pAttachments = &view_fragment_density_map.handle(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-02556"); |
| vk::CreateFramebuffer(device(), &fbci, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| { |
| // Create an image with one mip level. |
| VkImageObj image(m_device); |
| image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| ASSERT_TRUE(image.initialized()); |
| |
| // Create view attachment with non-identity swizzle |
| auto ivci = LvlInitStruct<VkImageViewCreateInfo>(); |
| ivci.image = image.handle(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| ivci.subresourceRange.layerCount = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| ivci.components.r = VK_COMPONENT_SWIZZLE_G; |
| ivci.components.g = VK_COMPONENT_SWIZZLE_R; |
| ivci.components.b = VK_COMPONENT_SWIZZLE_A; |
| ivci.components.a = VK_COMPONENT_SWIZZLE_B; |
| vk_testing::ImageView view(*m_device, ivci); |
| |
| fb_info.pAttachments = &view.handle(); |
| fb_info.height = 100; |
| fb_info.width = 100; |
| fb_info.layers = 1; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-pAttachments-00884"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| if (!multiview_supported) { |
| printf("VK_KHR_Multiview Extension not supported, skipping tests\n"); |
| } else { |
| // Test multiview renderpass with more than 1 layer |
| uint32_t viewMasks[] = {0x3u}; |
| auto rpmvci = LvlInitStruct<VkRenderPassMultiviewCreateInfo>(nullptr, 1u, viewMasks, 0u, nullptr, 0u, nullptr); |
| auto rpci_mv = LvlInitStruct<VkRenderPassCreateInfo>(&rpmvci, 0u, 0u, nullptr, 1u, &subpass, 0u, nullptr); |
| |
| VkFramebufferCreateInfo fb_info_mv = fb_info; |
| { |
| vk_testing::RenderPass rp_mv(*m_device, rpci_mv); |
| |
| fb_info_mv.layers = 2; |
| fb_info_mv.attachmentCount = 0; |
| fb_info_mv.renderPass = rp_mv.handle(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-renderPass-02531"); |
| vk::CreateFramebuffer(device(), &fb_info_mv, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkAttachmentDescription attach_desc_mv = {}; |
| attach_desc_mv.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc_mv.finalLayout = attach_desc_mv.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc_mv.samples = VK_SAMPLE_COUNT_1_BIT; |
| rpci_mv.attachmentCount = 1; |
| rpci_mv.pAttachments = &attach_desc_mv; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach; |
| vk_testing::RenderPass rp_mv(*m_device, rpci_mv); |
| |
| // Create an image with 1 layer |
| VkImageObj image(m_device); |
| image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| ASSERT_TRUE(image.initialized()); |
| |
| auto ivci = LvlInitStruct<VkImageViewCreateInfo>(); |
| ivci.image = image.handle(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| ivci.subresourceRange.layerCount = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk_testing::ImageView view(*m_device, ivci); |
| |
| fb_info_mv.renderPass = rp_mv.handle(); |
| fb_info_mv.layers = 1; |
| fb_info_mv.pAttachments = &view.handle(); |
| fb_info_mv.attachmentCount = 1; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-renderPass-04536"); |
| vk::CreateFramebuffer(device(), &fb_info_mv, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| // reset attachment to color attachment |
| fb_info.pAttachments = ivs; |
| |
| // Request fb that exceeds max width |
| fb_info.width = m_device->props.limits.maxFramebufferWidth + 1; |
| fb_info.height = 100; |
| fb_info.layers = 1; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-width-00886"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04533"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // and width=0 |
| fb_info.width = 0; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-width-00885"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // Request fb that exceeds max height |
| fb_info.width = 100; |
| fb_info.height = m_device->props.limits.maxFramebufferHeight + 1; |
| fb_info.layers = 1; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-height-00888"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04534"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // and height=0 |
| fb_info.height = 0; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-height-00887"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // Request fb that exceeds max layers |
| fb_info.width = 100; |
| fb_info.height = 100; |
| fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-layers-00890"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-flags-04535"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // and layers=0 |
| fb_info.layers = 0; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-layers-00889"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // Try to create with pAttachments = NULL |
| fb_info.layers = 1; |
| fb_info.pAttachments = NULL; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID_Undefined"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) { |
| TEST_DESCRIPTION("End a command buffer with an active render pass"); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkEndCommandBuffer-commandBuffer-00060"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); |
| vk::EndCommandBuffer(m_commandBuffer->handle()); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| // End command buffer properly to avoid driver issues. This is safe -- the |
| // previous vk::EndCommandBuffer should not have reached the driver. |
| m_commandBuffer->EndRenderPass(); |
| m_commandBuffer->end(); |
| |
| // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY |
| // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT |
| } |
| |
| TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithRenderPass) { |
| TEST_DESCRIPTION( |
| "Hit RenderPass incompatible cases. Initial case is drawing with an active renderpass that's not compatible with the bound " |
| "pipeline state object's creation renderpass"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| |
| const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_}); |
| |
| VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj fs(this, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT); // We shouldn't need a fragment shader |
| // but add it to be able to run on more devices |
| // Create a renderpass that will be incompatible with default renderpass |
| VkAttachmentReference color_att = {}; |
| color_att.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &color_att; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| VkPipelineObj pipe(m_device); |
| pipe.AddShader(&vs); |
| pipe.AddShader(&fs); |
| pipe.AddDefaultColorAttachment(); |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| m_viewports.push_back(viewport); |
| pipe.SetViewport(m_viewports); |
| VkRect2D rect = {{0, 0}, {64, 64}}; |
| m_scissors.push_back(rect); |
| pipe.SetScissor(m_scissors); |
| pipe.CreateVKPipeline(pipeline_layout.handle(), rp.handle()); |
| |
| auto cbii = LvlInitStruct<VkCommandBufferInheritanceInfo>(); |
| cbii.renderPass = rp.handle(); |
| cbii.subpass = 0; |
| auto cbbi = LvlInitStruct<VkCommandBufferBeginInfo>(); |
| cbbi.pInheritanceInfo = &cbii; |
| vk::BeginCommandBuffer(m_commandBuffer->handle(), &cbbi); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-renderPass-02684"); |
| // Render triangle (the error should trigger on the attempt to draw). |
| m_commandBuffer->Draw(3, 1, 0, 0); |
| |
| // Finalize recording of the command buffer |
| m_commandBuffer->EndRenderPass(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithRenderPassFragmentDensityMap) { |
| TEST_DESCRIPTION( |
| "Hit RenderPass incompatible case: drawing with an active renderpass that's not compatible with the bound pipeline state " |
| "object's creation renderpass since only the former uses a Fragment Density Map."); |
| |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| |
| const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_}); |
| |
| VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj fs(this, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT); // We shouldn't need a fragment shader |
| // but add it to be able to run on more devices |
| |
| VkAttachmentDescription attach = {}; |
| attach.format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| |
| VkAttachmentReference ref = {}; |
| ref.attachment = 0; |
| ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| auto rpfdmi = LvlInitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(); |
| rpfdmi.fragmentDensityMapAttachment = ref; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(&rpfdmi); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| |
| // Create rp1 with FDM pNext and rp2 without FDM pNext |
| vk_testing::RenderPass rp1(*m_device, rpci); |
| ASSERT_TRUE(rp1.initialized()); |
| |
| rpci.pNext = nullptr; |
| rpci.attachmentCount = 1; |
| vk_testing::RenderPass rp2(*m_device, rpci); |
| ASSERT_TRUE(rp2.initialized()); |
| |
| // Create image views |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| ASSERT_TRUE(image.initialized()); |
| |
| VkImageView iv = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); |
| |
| // Create a framebuffer with rp1 |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fbci.renderPass = rp1.handle(); |
| fbci.attachmentCount = 1; |
| fbci.pAttachments = &iv; |
| fbci.width = 128; |
| fbci.height = 128; |
| fbci.layers = 1; |
| |
| vk_testing::Framebuffer fb(*m_device, fbci); |
| ASSERT_TRUE(fb.initialized()); |
| |
| auto rp_begin = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rp_begin.renderPass = rp1.handle(); |
| rp_begin.framebuffer = fb.handle(); |
| rp_begin.renderArea = {{0, 0}, {128, 128}}; |
| |
| // Create a graphics pipeline with rp2 |
| VkPipelineObj pipe(m_device); |
| pipe.AddShader(&vs); |
| pipe.AddShader(&fs); |
| pipe.AddDefaultColorAttachment(); |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| m_viewports.push_back(viewport); |
| pipe.SetViewport(m_viewports); |
| VkRect2D rect = {{0, 0}, {64, 64}}; |
| m_scissors.push_back(rect); |
| pipe.SetScissor(m_scissors); |
| pipe.CreateVKPipeline(pipeline_layout.handle(), rp2.handle()); |
| |
| // Begin renderpass and bind to pipeline |
| auto cbii = LvlInitStruct<VkCommandBufferInheritanceInfo>(); |
| cbii.renderPass = rp1.handle(); |
| cbii.subpass = 0; |
| auto cbbi = LvlInitStruct<VkCommandBufferBeginInfo>(); |
| cbbi.pInheritanceInfo = &cbii; |
| vk::BeginCommandBuffer(m_commandBuffer->handle(), &cbbi); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-renderPass-02684"); |
| // Render triangle (the error should trigger on the attempt to draw). |
| m_commandBuffer->Draw(3, 1, 0, 0); |
| |
| // Finalize recording of the command buffer |
| m_commandBuffer->EndRenderPass(); |
| m_commandBuffer->end(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassMissingAttachment) { |
| TEST_DESCRIPTION("Begin render pass with missing framebuffer attachment"); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| // Create a renderPass with a single color attachment |
| VkAttachmentReference attach = {}; |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.pColorAttachments = &attach; |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| vk_testing::RenderPass rp(*m_device, rpci); |
| ASSERT_TRUE(rp.initialized()); |
| |
| auto createView = LvlInitStruct<VkImageViewCreateInfo>(); |
| createView.image = m_renderTargets[0]->handle(); |
| createView.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| createView.format = VK_FORMAT_B8G8R8A8_UNORM; |
| createView.components.r = VK_COMPONENT_SWIZZLE_R; |
| createView.components.g = VK_COMPONENT_SWIZZLE_G; |
| createView.components.b = VK_COMPONENT_SWIZZLE_B; |
| createView.components.a = VK_COMPONENT_SWIZZLE_A; |
| createView.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| createView.flags = 0; |
| |
| vk_testing::ImageView iv(*m_device, createView); |
| |
| auto fb_info = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fb_info.renderPass = rp.handle(); |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &iv.handle(); |
| fb_info.width = 100; |
| fb_info.height = 100; |
| fb_info.layers = 1; |
| |
| // Create the framebuffer then destory the view it uses. |
| vk_testing::Framebuffer fb(*m_device, fb_info); |
| ASSERT_TRUE(fb.initialized()); |
| iv.destroy(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-framebuffer-parameter"); |
| |
| auto rpbi = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbi.renderPass = rp.handle(); |
| rpbi.framebuffer = fb.handle(); |
| rpbi.renderArea = {{0, 0}, {32, 32}}; |
| |
| m_commandBuffer->begin(); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| // Don't call vk::CmdEndRenderPass; as the begin has been "skipped" based on the error condition |
| m_errorMonitor->VerifyFound(); |
| m_commandBuffer->end(); |
| } |
| |
| class RenderPassCreatePotentialFormatFeaturesTest : public VkLayerTest { |
| public: |
| void Test(bool const useLinearColorAttachment); |
| }; |
| |
| void RenderPassCreatePotentialFormatFeaturesTest::Test(bool const useLinearColorAttachment) { |
| // Check for VK_KHR_get_physical_device_properties2 |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| if (useLinearColorAttachment) { |
| AddRequiredExtensions(VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME); |
| } |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| if (useLinearColorAttachment) { |
| auto linear_color_attachment = LvlInitStruct<VkPhysicalDeviceLinearColorAttachmentFeaturesNV>(); |
| VkPhysicalDeviceFeatures2 features2 = GetPhysicalDeviceFeatures2(linear_color_attachment); |
| if (useLinearColorAttachment && !linear_color_attachment.linearColorAttachment) { |
| GTEST_SKIP() << "Test requires linearColorAttachment"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2)); |
| } else { |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| } |
| |
| PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; |
| PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; |
| if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { |
| GTEST_SKIP() << "Failed to load device profile layer."; |
| } |
| |
| // Set format features from being found |
| const VkFormat validColorFormat = VK_FORMAT_R8G8B8A8_UNORM; // guaranteed to be valid everywhere |
| const VkFormat invalidColorFormat = VK_FORMAT_B8G8R8A8_UNORM; |
| const VkFormat depthFormat = VK_FORMAT_D16_UNORM; |
| VkFormatProperties formatProps; |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), invalidColorFormat, &formatProps); |
| formatProps.linearTilingFeatures = 0; |
| formatProps.optimalTilingFeatures = 0; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), invalidColorFormat, formatProps); |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), depthFormat, &formatProps); |
| formatProps.linearTilingFeatures = 0; |
| formatProps.optimalTilingFeatures = 0; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), depthFormat, formatProps); |
| |
| VkAttachmentDescription attachments[4] = { |
| {0, validColorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL}, |
| {0, invalidColorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL}, |
| {0, validColorFormat, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL}, |
| {0, depthFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL}}; |
| |
| VkAttachmentReference references[4] = { |
| {0, VK_IMAGE_LAYOUT_GENERAL}, // valid color |
| {1, VK_IMAGE_LAYOUT_GENERAL}, // invalid color |
| {2, VK_IMAGE_LAYOUT_GENERAL}, // valid color multisample |
| {3, VK_IMAGE_LAYOUT_GENERAL} // invalid depth stencil |
| }; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.flags = 0; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.inputAttachmentCount = 0; |
| subpass.pInputAttachments = nullptr; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &references[0]; // valid |
| subpass.pResolveAttachments = nullptr; |
| subpass.pDepthStencilAttachment = nullptr; |
| subpass.preserveAttachmentCount = 0; |
| subpass.pPreserveAttachments = nullptr; |
| VkSubpassDescription originalSubpass = subpass; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(nullptr, 0u, 4u, attachments, 1u, &subpass, 0u, nullptr); |
| |
| // Color attachment |
| subpass.pColorAttachments = &references[1]; |
| if (useLinearColorAttachment) { |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-linearColorAttachment-06497", |
| "VUID-VkSubpassDescription2-linearColorAttachment-06500"); |
| } else { |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-pColorAttachments-02648", |
| "VUID-VkSubpassDescription2-pColorAttachments-02898"); |
| } |
| subpass = originalSubpass; |
| |
| // Input attachment |
| subpass.inputAttachmentCount = 1; |
| subpass.pInputAttachments = &references[1]; |
| if (useLinearColorAttachment) { |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-linearColorAttachment-06496", |
| "VUID-VkSubpassDescription2-linearColorAttachment-06499"); |
| } else { |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-pInputAttachments-02647", |
| "VUID-VkSubpassDescription2-pInputAttachments-02897"); |
| } |
| subpass = originalSubpass; |
| |
| // Depth Stencil attachment |
| subpass.pDepthStencilAttachment = &references[3]; |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-pDepthStencilAttachment-02650", |
| "VUID-VkSubpassDescription2-pDepthStencilAttachment-02900"); |
| subpass = originalSubpass; |
| |
| // Resolve attachment |
| subpass.pResolveAttachments = &references[1]; |
| subpass.pColorAttachments = &references[2]; // valid |
| // Can't use helper function due to need to set unexpected errors |
| { |
| VkRenderPass render_pass = VK_NULL_HANDLE; |
| |
| if (useLinearColorAttachment) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription-linearColorAttachment-06498"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription-pResolveAttachments-02649"); |
| } |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription-pResolveAttachments-00850"); |
| vk::CreateRenderPass(device(), &rpci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| |
| if (rp2Supported) { |
| PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = |
| (PFN_vkCreateRenderPass2KHR)vk::GetDeviceProcAddr(device(), "vkCreateRenderPass2KHR"); |
| safe_VkRenderPassCreateInfo2 create_info2 = ConvertVkRenderPassCreateInfoToV2KHR(rpci); |
| |
| if (useLinearColorAttachment) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-linearColorAttachment-06501"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-pResolveAttachments-02899"); |
| } |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription2-pResolveAttachments-03068"); |
| vkCreateRenderPass2KHR(device(), create_info2.ptr(), nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| |
| // For api version >= 1.2, try core entrypoint |
| PFN_vkCreateRenderPass2 vkCreateRenderPass2 = |
| (PFN_vkCreateRenderPass2)vk::GetDeviceProcAddr(device(), "vkCreateRenderPass2"); |
| if (vkCreateRenderPass2) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-pResolveAttachments-02899"); |
| m_errorMonitor->SetUnexpectedError("VUID-VkSubpassDescription2-pResolveAttachments-03068"); |
| vkCreateRenderPass2(device(), create_info2.ptr(), nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| } |
| } |
| |
| TEST_F(RenderPassCreatePotentialFormatFeaturesTest, Core) { |
| TEST_DESCRIPTION("Validate PotentialFormatFeatures in renderpass create"); |
| |
| Test(false); |
| } |
| |
| TEST_F(RenderPassCreatePotentialFormatFeaturesTest, LinearColorAttachment) { |
| TEST_DESCRIPTION("Validate PotentialFormatFeatures in renderpass create with linearColorAttachment"); |
| |
| Test(true); |
| } |
| |
| TEST_F(VkLayerTest, DepthStencilResolveMode) { |
| TEST_DESCRIPTION("Test valid usage of the VkResolveModeFlagBits"); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = |
| (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR"); |
| assert(vkGetPhysicalDeviceProperties2KHR != nullptr); |
| PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = |
| (PFN_vkCreateRenderPass2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); |
| assert(vkCreateRenderPass2KHR != nullptr); |
| |
| VkFormat depthFormat = FindSupportedDepthOnlyFormat(gpu()); |
| VkFormat depthStencilFormat = FindSupportedDepthStencilFormat(gpu()); |
| VkFormat stencilFormat = FindSupportedStencilOnlyFormat(gpu()); |
| if (stencilFormat == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "Couldn't find a stencil only image format"; |
| } |
| |
| auto ds_resolve_props = LvlInitStruct<VkPhysicalDeviceDepthStencilResolveProperties>(); |
| auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&ds_resolve_props); |
| vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2); |
| |
| VkRenderPass renderPass; |
| |
| VkAttachmentDescription2KHR attachmentDescriptions[2] = {}; |
| // Depth/stencil attachment |
| attachmentDescriptions[0] = LvlInitStruct<VkAttachmentDescription2KHR>(); |
| attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| // Depth/stencil resolve attachment |
| attachmentDescriptions[1] = LvlInitStruct<VkAttachmentDescription2KHR>(); |
| attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| |
| auto depthStencilAttachmentReference = LvlInitStruct<VkAttachmentReference2KHR>(); |
| depthStencilAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilAttachmentReference.attachment = 0; |
| auto depthStencilResolveAttachmentReference = LvlInitStruct<VkAttachmentReference2KHR>(); |
| depthStencilResolveAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilResolveAttachmentReference.attachment = 1; |
| auto subpassDescriptionDSR = LvlInitStruct<VkSubpassDescriptionDepthStencilResolveKHR>(); |
| subpassDescriptionDSR.pDepthStencilResolveAttachment = &depthStencilResolveAttachmentReference; |
| auto subpassDescription = LvlInitStruct<VkSubpassDescription2KHR>(&subpassDescriptionDSR); |
| subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentReference; |
| |
| auto renderPassCreateInfo = LvlInitStruct<VkRenderPassCreateInfo2KHR>(); |
| renderPassCreateInfo.attachmentCount = 2; |
| renderPassCreateInfo.subpassCount = 1; |
| renderPassCreateInfo.pSubpasses = &subpassDescription; |
| renderPassCreateInfo.pAttachments = attachmentDescriptions; |
| |
| // Both modes can't be none |
| attachmentDescriptions[0].format = depthStencilFormat; |
| attachmentDescriptions[1].format = depthStencilFormat; |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_NONE; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_NONE; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03178"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| |
| // Stencil is used but resolve is set to none, depthResolveMode should be ignored |
| attachmentDescriptions[0].format = stencilFormat; |
| attachmentDescriptions[1].format = stencilFormat; |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_NONE; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03178"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| |
| // Invalid use of UNUSED |
| depthStencilAttachmentReference.attachment = VK_ATTACHMENT_UNUSED; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03177"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| depthStencilAttachmentReference.attachment = 0; |
| |
| // attachmentCount == 2 |
| depthStencilResolveAttachmentReference.attachment = 2; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassCreateInfo2-pSubpasses-06473"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| depthStencilResolveAttachmentReference.attachment = 1; |
| |
| // test invalid sample counts |
| attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03179"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| |
| attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_4_BIT; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03180"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| |
| // test resolve and non-resolve formats are not same types |
| attachmentDescriptions[0].format = stencilFormat; |
| attachmentDescriptions[1].format = depthFormat; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03181"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| |
| attachmentDescriptions[0].format = depthFormat; |
| attachmentDescriptions[1].format = stencilFormat; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03182"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| |
| // test when independentResolve and independentResolve are false |
| attachmentDescriptions[0].format = depthStencilFormat; |
| attachmentDescriptions[1].format = depthStencilFormat; |
| if (ds_resolve_props.independentResolve == VK_FALSE) { |
| if (ds_resolve_props.independentResolveNone == VK_FALSE) { |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_NONE; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| m_errorMonitor->SetDesiredFailureMsg( |
| kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03185"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| } else { |
| if ((ds_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0) { |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| m_errorMonitor->SetDesiredFailureMsg( |
| kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03186"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| } |
| if ((ds_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0) { |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| m_errorMonitor->SetDesiredFailureMsg( |
| kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03186"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| } else { |
| // test using unsupported resolve mode, which currently can only be AVERAGE |
| // Need independentResolve to make easier to test |
| if ((ds_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) == 0) { |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-depthResolveMode-03183"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| } |
| if ((ds_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) == 0) { |
| subpassDescriptionDSR.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| subpassDescriptionDSR.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-stencilResolveMode-03184"); |
| vkCreateRenderPass2KHR(m_device->device(), &renderPassCreateInfo, nullptr, &renderPass); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| } |
| |
| TEST_F(VkLayerTest, InvalidRenderArea) { |
| TEST_DESCRIPTION("Begin render pass with render area that is not within the framebuffer."); |
| |
| AddOptionalExtensions(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| const bool device_group_supported = IsExtensionsEnabled(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); |
| |
| auto rpbinfo = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbinfo.renderPass = m_renderPass; |
| rpbinfo.framebuffer = m_framebuffer; |
| rpbinfo.renderArea.extent.width = m_framebuffer_info.width; |
| rpbinfo.renderArea.extent.height = m_framebuffer_info.height; |
| rpbinfo.renderArea.offset.x = -32; |
| rpbinfo.renderArea.offset.y = 0; |
| rpbinfo.clearValueCount = 1; |
| rpbinfo.pClearValues = m_renderPassClearValues.data(); |
| |
| m_commandBuffer->begin(); |
| |
| if (device_group_supported) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02850"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderArea-02846"); |
| } |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| rpbinfo.renderArea.offset.x = 0; |
| rpbinfo.renderArea.offset.y = -128; |
| |
| if (device_group_supported) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02851"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderArea-02847"); |
| } |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| rpbinfo.renderArea.offset.y = 0; |
| rpbinfo.renderArea.extent.width = m_framebuffer_info.width + 128; |
| |
| if (device_group_supported) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02852"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderArea-02848"); |
| } |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| rpbinfo.renderArea.extent.width = m_framebuffer_info.width; |
| rpbinfo.renderArea.extent.height = m_framebuffer_info.height + 1; |
| |
| if (device_group_supported) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02853"); |
| } else { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderArea-02849"); |
| } |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(VkLayerTest, InvalidDeviceGroupRenderArea) { |
| TEST_DESCRIPTION("Begin render pass with device group render area that is not within the framebuffer."); |
| |
| AddRequiredExtensions(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| VkRect2D renderArea = {}; |
| renderArea.offset.x = -1; |
| renderArea.offset.y = -1; |
| renderArea.extent.width = 64; |
| renderArea.extent.height = 64; |
| |
| auto device_group_render_pass_begin_info = LvlInitStruct<VkDeviceGroupRenderPassBeginInfo>(); |
| device_group_render_pass_begin_info.deviceMask = 0x1; |
| device_group_render_pass_begin_info.deviceRenderAreaCount = 1; |
| device_group_render_pass_begin_info.pDeviceRenderAreas = &renderArea; |
| |
| auto rpbinfo = LvlInitStruct<VkRenderPassBeginInfo>(&device_group_render_pass_begin_info); |
| rpbinfo.renderPass = m_renderPass; |
| rpbinfo.framebuffer = m_framebuffer; |
| rpbinfo.renderArea.extent.width = m_framebuffer_info.width; |
| rpbinfo.renderArea.extent.height = m_framebuffer_info.height; |
| rpbinfo.renderArea.offset.x = -32; |
| rpbinfo.renderArea.offset.y = 0; |
| rpbinfo.clearValueCount = 1; |
| rpbinfo.pClearValues = m_renderPassClearValues.data(); |
| |
| m_commandBuffer->begin(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceGroupRenderPassBeginInfo-offset-06166"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceGroupRenderPassBeginInfo-offset-06167"); |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| renderArea.offset.x = 0; |
| renderArea.offset.y = 1; |
| renderArea.extent.width = m_framebuffer_info.width + 1; |
| renderArea.extent.height = m_framebuffer_info.height; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02856"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-pNext-02857"); |
| m_commandBuffer->BeginRenderPass(rpbinfo); |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(VkLayerTest, RenderPassBeginNullValues) { |
| TEST_DESCRIPTION("Test invalid null entries for clear color"); |
| |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| auto rpbi = m_renderPassBeginInfo; |
| rpbi.clearValueCount = 1; |
| rpbi.pClearValues = nullptr; // clearValueCount != 0, but pClearValues = null, leads to 04962 |
| TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rpbi, false, |
| "VUID-VkRenderPassBeginInfo-clearValueCount-04962", nullptr); |
| } |
| |
| TEST_F(VkLayerTest, DepthStencilResolveAttachmentInvalidFormat) { |
| TEST_DESCRIPTION("Create subpass with VkSubpassDescriptionDepthStencilResolve that has an "); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentDescription2KHR attachmentDescriptions[2] = {}; |
| // Depth/stencil attachment |
| attachmentDescriptions[0] = LvlInitStruct<VkAttachmentDescription2>(); |
| attachmentDescriptions[0].format = VK_FORMAT_R8_UNORM; |
| attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| // Depth/stencil resolve attachment |
| attachmentDescriptions[1] = LvlInitStruct<VkAttachmentDescription2>(); |
| attachmentDescriptions[1].format = ds_format; |
| attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| |
| auto depthStencilAttachmentReference = LvlInitStruct<VkAttachmentReference2KHR>(); |
| depthStencilAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilAttachmentReference.attachment = 1; |
| |
| auto depthStencilResolveAttachmentReference = LvlInitStruct<VkAttachmentReference2KHR>(); |
| depthStencilResolveAttachmentReference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthStencilResolveAttachmentReference.attachment = 0; |
| |
| auto subpassDescriptionDepthStencilResolve = LvlInitStruct<VkSubpassDescriptionDepthStencilResolveKHR>(); |
| subpassDescriptionDepthStencilResolve.pDepthStencilResolveAttachment = &depthStencilResolveAttachmentReference; |
| subpassDescriptionDepthStencilResolve.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| subpassDescriptionDepthStencilResolve.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| |
| auto subpassDescription = LvlInitStruct<VkSubpassDescription2>(&subpassDescriptionDepthStencilResolve); |
| subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentReference; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpassDescription; |
| rpci.attachmentCount = 2; |
| rpci.pAttachments = attachmentDescriptions; |
| |
| PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = |
| (PFN_vkCreateRenderPass2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); |
| |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, |
| "VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-02651"); |
| vkCreateRenderPass2KHR(m_device->device(), &rpci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, InvalidRenderPassAttachmentFormat) { |
| TEST_DESCRIPTION("Test creating render pass with attachment format VK_FORMAT_UNDEFINED"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_SWAPCHAIN_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (DeviceValidationVersion() < VK_API_VERSION_1_2) { |
| GTEST_SKIP() << "At least Vulkan version 1.2 is required"; |
| } |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported."; |
| } |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_UNDEFINED; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; |
| |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; |
| |
| auto render_pass_ci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| render_pass_ci.attachmentCount = 1; |
| render_pass_ci.pAttachments = &attach_desc; |
| render_pass_ci.subpassCount = 1; |
| render_pass_ci.pSubpasses = &subpass; |
| |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription-format-06698"); |
| vk::CreateRenderPass(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| |
| auto attach_desc_2 = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc_2.format = VK_FORMAT_UNDEFINED; |
| attach_desc_2.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc_2.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc_2.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto subpass_2 = LvlInitStruct<VkSubpassDescription2>(); |
| |
| auto render_pass_ci_2 = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| render_pass_ci_2.attachmentCount = 1; |
| render_pass_ci_2.pAttachments = &attach_desc_2; |
| render_pass_ci_2.subpassCount = 1; |
| render_pass_ci_2.pSubpasses = &subpass_2; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription2-format-06698"); |
| vk::CreateRenderPass2(device(), &render_pass_ci_2, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, SamplingFromReadOnlyDepthStencilAttachment) { |
| TEST_DESCRIPTION("Use same image as depth stencil attachment in read only layer and as sampler"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| const uint32_t width = 32; |
| const uint32_t height = 32; |
| const VkFormat format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkAttachmentReference attach_ref = {}; |
| attach_ref.attachment = 0; |
| attach_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.pDepthStencilAttachment = &attach_ref; |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = format; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| |
| vk_testing::RenderPass render_pass(*m_device, rpci); |
| |
| auto image_create_info = LvlInitStruct<VkImageCreateInfo>(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = format; |
| image_create_info.extent.width = width; |
| image_create_info.extent.height = height; |
| image_create_info.extent.depth = 1; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| image_create_info.flags = 0; |
| |
| VkImageObj image(m_device); |
| image.init(&image_create_info); |
| |
| auto ivci = LvlInitStruct<VkImageViewCreateInfo>(); |
| ivci.image = image.handle(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = format; |
| ivci.subresourceRange.layerCount = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.baseArrayLayer = 0; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| vk_testing::ImageView image_view; |
| image_view.init(*m_device, ivci); |
| VkImageView image_view_handle = image_view.handle(); |
| |
| vk_testing::Sampler sampler; |
| VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); |
| sampler.init(*m_device, sampler_ci); |
| |
| auto fbci = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fbci.width = width; |
| fbci.height = height; |
| fbci.layers = 1; |
| fbci.renderPass = render_pass.handle(); |
| fbci.attachmentCount = 1; |
| fbci.pAttachments = &image_view_handle; |
| |
| vk_testing::Framebuffer framebuffer(*m_device, fbci); |
| |
| auto rpbi = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbi.framebuffer = framebuffer.handle(); |
| rpbi.renderPass = render_pass.handle(); |
| rpbi.renderArea.extent.width = width; |
| rpbi.renderArea.extent.height = height; |
| rpbi.clearValueCount = 1; |
| rpbi.pClearValues = m_renderPassClearValues.data(); |
| |
| char const *fsSource = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) uniform sampler2D depth; |
| void main(){ |
| vec4 color = texture(depth, ivec2(0)); |
| } |
| )glsl"; |
| |
| VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkPipelineObj pipe(m_device); |
| pipe.AddDefaultColorAttachment(); |
| pipe.AddShader(&vs); |
| pipe.AddShader(&fs); |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| m_viewports.push_back(viewport); |
| pipe.SetViewport(m_viewports); |
| VkRect2D rect = {}; |
| m_scissors.push_back(rect); |
| pipe.SetScissor(m_scissors); |
| auto pipe_ds_state_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>(); |
| pipe_ds_state_ci.depthTestEnable = VK_TRUE; |
| pipe_ds_state_ci.stencilTestEnable = VK_FALSE; |
| pipe.SetDepthStencil(&pipe_ds_state_ci); |
| |
| VkDescriptorSetLayoutBinding layout_binding = {}; |
| layout_binding.binding = 0; |
| layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
| layout_binding.descriptorCount = 1; |
| layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; |
| layout_binding.pImmutableSamplers = nullptr; |
| const VkDescriptorSetLayoutObj descriptor_set_layout(m_device, {layout_binding}); |
| |
| const VkPipelineLayoutObj pipeline_layout(DeviceObj(), {&descriptor_set_layout, &descriptor_set_layout}); |
| pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| VkDescriptorImageInfo image_info = {}; |
| image_info.sampler = sampler.handle(); |
| image_info.imageView = image_view.handle(); |
| image_info.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; |
| auto descriptor_write = LvlInitStruct<VkWriteDescriptorSet>(); |
| descriptor_write.dstSet = descriptor_set.set_; |
| descriptor_write.dstBinding = 0; |
| descriptor_write.descriptorCount = 1; |
| descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
| descriptor_write.pImageInfo = &image_info; |
| vk::UpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, nullptr); |
| |
| m_commandBuffer->begin(); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, |
| &descriptor_set.set_, 0, nullptr); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| vk::CmdEndRenderPass(m_commandBuffer->handle()); |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(VkLayerTest, TestColorAttachmentImageViewUsage) { |
| TEST_DESCRIPTION("Create image view with missing usage bits."); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported."; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, |
| VK_IMAGE_TILING_OPTIMAL, 0); |
| |
| auto image_view_usage = LvlInitStruct<VkImageViewUsageCreateInfo>(); |
| image_view_usage.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| |
| auto image_view_ci = LvlInitStruct<VkImageViewCreateInfo>(&image_view_usage); |
| image_view_ci.image = image.handle(); |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_view_ci.subresourceRange.layerCount = 1; |
| image_view_ci.subresourceRange.baseMipLevel = 0; |
| image_view_ci.subresourceRange.levelCount = 1; |
| image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| |
| vk_testing::ImageView image_view; |
| image_view.init(*m_device, image_view_ci); |
| |
| vk_testing::Sampler sampler; |
| VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); |
| sampler.init(*m_device, sampler_ci); |
| |
| VkDescriptorImageInfo image_info = {}; |
| image_info.sampler = sampler.handle(); |
| image_info.imageView = image_view.handle(); |
| image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
| |
| auto descriptor_write = LvlInitStruct<VkWriteDescriptorSet>(); |
| descriptor_write.dstSet = descriptor_set.set_; |
| descriptor_write.dstBinding = 0; |
| descriptor_write.descriptorCount = 1; |
| descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
| descriptor_write.pImageInfo = &image_info; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00337"); |
| vk::UpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, CreateRenderPassWithInvalidStencilLoadOp) { |
| TEST_DESCRIPTION("Create render pass with invalid stencil load op."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| |
| if (DeviceValidationVersion() < VK_API_VERSION_1_1) { |
| GTEST_SKIP() << "At least Vulkan version 1.1 is required"; |
| } |
| |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| const VkFormat stencil_format = FindSupportedStencilOnlyFormat(gpu()); |
| if (stencil_format == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "Couldn't find a stencil only image format"; |
| } |
| |
| auto vkCreateRenderPass2KHR = |
| reinterpret_cast<PFN_vkCreateRenderPass2KHR>(vk::GetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR")); |
| |
| auto attach_desc = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc.format = stencil_format; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
| |
| auto subpass = LvlInitStruct<VkSubpassDescription2>(); |
| |
| auto render_pass_ci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| render_pass_ci.subpassCount = 1; |
| render_pass_ci.pSubpasses = &subpass; |
| render_pass_ci.attachmentCount = 1; |
| render_pass_ci.pAttachments = &attach_desc; |
| |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription2-pNext-06704"); |
| vkCreateRenderPass2KHR(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto attach_desc_stencil_layout = LvlInitStruct<VkAttachmentDescriptionStencilLayout>(); |
| attach_desc_stencil_layout.stencilInitialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc_stencil_layout.stencilFinalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.pNext = &attach_desc_stencil_layout; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription2-pNext-06705"); |
| vkCreateRenderPass2KHR(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, CreateRenderPassWithViewMask) { |
| TEST_DESCRIPTION("Create render pass with view mask, but multiview feature disabled."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| |
| if (DeviceValidationVersion() < VK_API_VERSION_1_1) { |
| GTEST_SKIP() << "At least Vulkan version 1.1 is required"; |
| } |
| |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| auto vkCreateRenderPass2KHR = |
| reinterpret_cast<PFN_vkCreateRenderPass2KHR>(vk::GetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR")); |
| |
| auto attach_desc = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto subpass = LvlInitStruct<VkSubpassDescription2>(); |
| subpass.viewMask = 0x1; |
| |
| auto render_pass_ci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| render_pass_ci.subpassCount = 1; |
| render_pass_ci.pSubpasses = &subpass; |
| render_pass_ci.attachmentCount = 1; |
| render_pass_ci.pAttachments = &attach_desc; |
| |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-multiview-06558"); |
| vkCreateRenderPass2KHR(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, TestAllViewMasksZero) { |
| TEST_DESCRIPTION("Test VkRenderPassMultiviewCreateInfo with all view mask elements being 0."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| if (DeviceValidationVersion() < VK_API_VERSION_1_1) { |
| GTEST_SKIP() << "At least Vulkan version 1.1 is required"; |
| } |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| |
| VkSubpassDependency dependency = {}; |
| dependency.dependencyFlags = VK_DEPENDENCY_VIEW_LOCAL_BIT; |
| dependency.srcSubpass = 0; |
| dependency.dstSubpass = VK_SUBPASS_EXTERNAL; |
| dependency.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |
| dependency.dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |
| |
| auto render_pass_multiview_ci = LvlInitStruct<VkRenderPassMultiviewCreateInfo>(); |
| auto render_pass_ci = LvlInitStruct<VkRenderPassCreateInfo>(&render_pass_multiview_ci); |
| render_pass_ci.subpassCount = 1; |
| render_pass_ci.pSubpasses = &subpass_description; |
| render_pass_ci.dependencyCount = 1; |
| render_pass_ci.pDependencies = &dependency; |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassCreateInfo-pNext-02514"); |
| vk::CreateRenderPass(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| |
| uint32_t correlation_mask = 0x1; |
| render_pass_ci.dependencyCount = 0; |
| render_pass_multiview_ci.correlationMaskCount = 1; |
| render_pass_multiview_ci.pCorrelationMasks = &correlation_mask; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassCreateInfo-pNext-02515"); |
| vk::CreateRenderPass(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, InvalidRenderPassAttachmentUndefinedLayout) { |
| TEST_DESCRIPTION("Create render pass with invalid attachment undefined layout."); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| const bool rp2Supported = IsExtensionsEnabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| ASSERT_NO_FATAL_FAILURE(InitState()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu()); |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = ds_format; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| |
| TestRenderPassCreate(m_errorMonitor, device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-format-06699", |
| "VUID-VkAttachmentDescription2-format-06699"); |
| |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription-format-06700"); |
| VkRenderPass render_pass; |
| vk::CreateRenderPass(device(), &rpci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, MultisampledRenderToSingleSampled) { |
| TEST_DESCRIPTION("Test VK_EXT_multisampled_render_to_single_sampled"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| |
| AddRequiredExtensions(VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddOptionalExtensions(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| |
| if (DeviceValidationVersion() < VK_API_VERSION_1_2) { |
| GTEST_SKIP() << "At least Vulkan version 1.2 is required"; |
| } |
| if (!AreRequiredExtensionsEnabled()) { |
| GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported"; |
| } |
| |
| auto dynamic_rendering_features = LvlInitStruct<VkPhysicalDeviceDynamicRenderingFeaturesKHR>(); |
| auto ms_render_to_single_sampled_features = |
| LvlInitStruct<VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT>(&dynamic_rendering_features); |
| auto imageless_features = LvlInitStruct<VkPhysicalDeviceImagelessFramebufferFeaturesKHR>(&ms_render_to_single_sampled_features); |
| GetPhysicalDeviceFeatures2(imageless_features); |
| |
| bool imageless_fb_supported = IsExtensionsEnabled(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME); |
| |
| auto vulkan_12_features = LvlInitStruct<VkPhysicalDeviceVulkan12Properties>(); |
| auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&vulkan_12_features); |
| GetPhysicalDeviceProperties2(prop2); |
| |
| ms_render_to_single_sampled_features.multisampledRenderToSingleSampled = true; |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &imageless_features, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| auto attachmentRef = LvlInitStruct<VkAttachmentReference2>(); |
| attachmentRef.layout = VK_IMAGE_LAYOUT_GENERAL; |
| attachmentRef.attachment = 0; |
| auto depthRef = LvlInitStruct<VkAttachmentReference2>(); |
| depthRef.layout = VK_IMAGE_LAYOUT_GENERAL; |
| depthRef.attachment = 1; |
| |
| auto ms_render_to_ss = LvlInitStruct<VkMultisampledRenderToSingleSampledInfoEXT>(); |
| ms_render_to_ss.multisampledRenderToSingleSampledEnable = VK_TRUE; |
| ms_render_to_ss.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT; |
| |
| auto subpass = LvlInitStruct<VkSubpassDescription2>(&ms_render_to_ss); |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attachmentRef; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 2; |
| |
| VkAttachmentDescription2 attach_desc[2] = {}; |
| attach_desc[0] = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; |
| attach_desc[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attach_desc[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc[1] = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc[1].format = VK_FORMAT_D32_SFLOAT; |
| attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| rpci.pAttachments = attach_desc; |
| |
| VkRenderPass rp; |
| // attach_desc[0].samples != ms_state.rasterizationSamples |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-pNext-06870"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| |
| attach_desc[0].samples = VK_SAMPLE_COUNT_2_BIT; |
| subpass.pDepthStencilAttachment = &depthRef; |
| // Depth VK_SAMPLE_COUNT_1_BIT, no VkSubpassDescriptionDepthStencilResolve in pNext |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescription2-pNext-06871"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| |
| auto depth_stencil_resolve = LvlInitStruct<VkSubpassDescriptionDepthStencilResolve>(); |
| ms_render_to_ss.pNext = &depth_stencil_resolve; |
| // VkSubpassDescriptionDepthStencilResolve depthResolveMode and stencilResolveMode both VK_RESOLVE_MODE_NONE |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pNext-06873"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| |
| VkResolveModeFlagBits unsupported_depth = VK_RESOLVE_MODE_NONE; |
| VkResolveModeFlagBits supported_depth = VK_RESOLVE_MODE_NONE; |
| VkResolveModeFlagBits unsupported_stencil = VK_RESOLVE_MODE_NONE; |
| VkResolveModeFlagBits supported_stencil = VK_RESOLVE_MODE_NONE; |
| for (VkResolveModeFlagBits i = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; i <= VK_RESOLVE_MODE_MAX_BIT; |
| i = VkResolveModeFlagBits(i << 1)) { |
| if ((unsupported_depth == VK_RESOLVE_MODE_NONE) && !(i & vulkan_12_features.supportedDepthResolveModes)) { |
| unsupported_depth = i; |
| } |
| if ((unsupported_stencil == VK_RESOLVE_MODE_NONE) && !(i & vulkan_12_features.supportedStencilResolveModes)) { |
| unsupported_stencil = i; |
| } |
| if (supported_stencil == VK_RESOLVE_MODE_NONE) { |
| if (i & vulkan_12_features.supportedDepthResolveModes) { |
| supported_stencil = i; |
| } |
| } else if (supported_depth == VK_RESOLVE_MODE_NONE) { |
| // Want supported depth different than supported stencil |
| if (i & vulkan_12_features.supportedDepthResolveModes) { |
| supported_depth = i; |
| } |
| } |
| } |
| if (unsupported_depth != VK_RESOLVE_MODE_NONE) { |
| depth_stencil_resolve.depthResolveMode = unsupported_depth; |
| // depthResolveMode unsupported |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pNext-06874"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| depth_stencil_resolve.depthResolveMode = VK_RESOLVE_MODE_NONE; |
| } |
| |
| if (unsupported_stencil != VK_RESOLVE_MODE_NONE) { |
| attach_desc[1].format = VK_FORMAT_S8_UINT; |
| depth_stencil_resolve.stencilResolveMode = unsupported_stencil; |
| // stencilResolveMode unsupported |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pNext-06875"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| depth_stencil_resolve.stencilResolveMode = VK_RESOLVE_MODE_NONE; |
| attach_desc[1].format = VK_FORMAT_D32_SFLOAT; |
| } |
| |
| if (!(vulkan_12_features.independentResolve) && !(vulkan_12_features.independentResolveNone) && |
| (supported_depth != VK_RESOLVE_MODE_NONE) && (supported_stencil != VK_RESOLVE_MODE_NONE)) { |
| depth_stencil_resolve.depthResolveMode = supported_depth; |
| depth_stencil_resolve.stencilResolveMode = supported_stencil; |
| attach_desc[1].format = VK_FORMAT_D32_SFLOAT_S8_UINT; |
| // Stencil and depth resolve modes must be the same |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pNext-06876"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| if (!(vulkan_12_features.independentResolve) && vulkan_12_features.independentResolveNone && |
| (supported_depth != VK_RESOLVE_MODE_NONE) && (supported_stencil != VK_RESOLVE_MODE_NONE)) { |
| depth_stencil_resolve.depthResolveMode = supported_depth; |
| depth_stencil_resolve.stencilResolveMode = supported_stencil; |
| attach_desc[1].format = VK_FORMAT_D32_SFLOAT_S8_UINT; |
| // Stencil and depth resolve modes must be the same or one of them must be VK_RESOLVE_MODE_NONE |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubpassDescriptionDepthStencilResolve-pNext-06877"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| ms_render_to_ss.pNext = nullptr; |
| subpass.pDepthStencilAttachment = nullptr; |
| ms_render_to_ss.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| // rasterizationSamples can't be VK_SAMPLE_COUNT_1_BIT |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMultisampledRenderToSingleSampledInfoEXT-rasterizationSamples-06878"); |
| vk::CreateRenderPass2(device(), &rpci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| attach_desc[0].samples = VK_SAMPLE_COUNT_2_BIT; |
| |
| ms_render_to_ss.pNext = nullptr; |
| ms_render_to_ss.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT; |
| subpass.pDepthStencilAttachment = nullptr; |
| rpci.attachmentCount = 1; |
| // Create a usable renderpass |
| vk_testing::RenderPass test_rp(*m_device, rpci); |
| |
| auto ms_state = LvlInitStruct<VkPipelineMultisampleStateCreateInfo>(); |
| ms_state.flags = 0; |
| ms_state.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| ms_state.sampleShadingEnable = VK_FALSE; |
| ms_state.minSampleShading = 0.0f; |
| ms_state.pSampleMask = nullptr; |
| ms_state.alphaToCoverageEnable = VK_FALSE; |
| ms_state.alphaToOneEnable = VK_FALSE; |
| |
| CreatePipelineHelper pipe_helper(*this); |
| pipe_helper.InitInfo(); |
| pipe_helper.InitState(); |
| pipe_helper.gp_ci_.renderPass = test_rp.handle(); |
| pipe_helper.pipe_ms_state_ci_ = ms_state; |
| |
| // ms_render_to_ss.rasterizationSamples != ms_state.rasterizationSamples |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-renderPass-06854"); |
| pipe_helper.CreateGraphicsPipeline(); |
| m_errorMonitor->VerifyFound(); |
| |
| // Actually create a usable pipeline |
| pipe_helper.pipe_ms_state_ci_.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT; |
| pipe_helper.CreateGraphicsPipeline(); |
| |
| auto color_attachment = LvlInitStruct<VkRenderingAttachmentInfoKHR>(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| ms_render_to_ss.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| auto begin_rendering_info = LvlInitStruct<VkRenderingInfoKHR>(&ms_render_to_ss); |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| // ms_render_to_ss.rasterizationSamples != ms_state.rasterizationSamples |
| // Valid because never hit draw time |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_helper.pipeline_); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| auto image_format_prop = LvlInitStruct<VkImageFormatProperties2>(); |
| auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(); |
| image_format_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_format_info.type = VK_IMAGE_TYPE_2D; |
| image_format_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_format_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| VkResult result = vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop); |
| if ((result != VK_SUCCESS) || !(image_format_prop.imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_2_BIT)) { |
| GTEST_SKIP() << "Cannot create an image with format VK_FORMAT_B8G8R8A8_UNORM and sample count VK_SAMPLE_COUNT_2_BIT. " |
| "Skipping remainder of the test"; |
| } |
| |
| auto image_create_info = LvlInitStruct<VkImageCreateInfo>(); |
| image_create_info.flags = 0; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {64, 64, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
| image_create_info.queueFamilyIndexCount = 0; |
| image_create_info.pQueueFamilyIndices = nullptr; |
| image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| VkImageObj two_count_image(m_device); |
| two_count_image.init(&image_create_info); |
| |
| vk_testing::ImageView two_count_image_view; |
| auto image_view_ci = two_count_image.TargetViewCI(VK_FORMAT_B8G8R8A8_UNORM); |
| image_view_ci.image = two_count_image.handle(); |
| two_count_image_view.init(*m_device, image_view_ci); |
| |
| color_attachment.imageView = two_count_image_view.handle(); |
| m_commandBuffer->begin(); |
| // Attachments must have a sample count that is either VK_SAMPLE_COUNT_1_BIT or |
| // VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples. |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderingInfo-imageView-06858"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| VkImageObj one_count_image(m_device); |
| one_count_image.init(&image_create_info); |
| vk_testing::ImageView one_count_image_view; |
| auto one_count_image_view_ci = one_count_image.TargetViewCI(VK_FORMAT_B8G8R8A8_UNORM); |
| one_count_image_view_ci.image = one_count_image.handle(); |
| one_count_image_view.init(*m_device, one_count_image_view_ci); |
| color_attachment.imageView = one_count_image_view.handle(); |
| // Attachments with a sample count of VK_SAMPLE_COUNT_1_BIT must have been created with |
| // VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderingInfo-imageView-06859"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| color_attachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkImageObj good_one_count_image(m_device); |
| image_create_info.flags = VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT; |
| good_one_count_image.init(&image_create_info); |
| vk_testing::ImageView good_one_count_image_view; |
| auto good_one_count_image_view_ci = good_one_count_image.TargetViewCI(VK_FORMAT_B8G8R8A8_UNORM); |
| good_one_count_image_view_ci.image = good_one_count_image.handle(); |
| good_one_count_image_view.init(*m_device, good_one_count_image_view_ci); |
| color_attachment.imageView = good_one_count_image_view.handle(); |
| color_attachment.resolveImageView = good_one_count_image_view.handle(); |
| color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| begin_rendering_info.pNext = nullptr; |
| color_attachment.imageView = good_one_count_image_view.handle(); |
| // If resolveMode is not VK_RESOLVE_MODE_NONE, imageView must not have a sample count of VK_SAMPLE_COUNT_1_BIT |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderingAttachmentInfo-imageView-06861"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| color_attachment.imageView = two_count_image_view.handle(); |
| color_attachment.resolveImageView = VK_NULL_HANDLE; |
| // If resolveMode is not VK_RESOLVE_MODE_NONE, resolveImageView must not be VK_NULL_HANDLE |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderingAttachmentInfo-imageView-06862"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| begin_rendering_info.pNext = &ms_render_to_ss; |
| color_attachment.imageView = good_one_count_image_view.handle(); |
| color_attachment.resolveImageView = good_one_count_image_view.handle(); |
| // If imageView has a sample count of VK_SAMPLE_COUNT_1_BIT, resolveImageView must be VK_NULL_HANDLE |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderingAttachmentInfo-imageView-06863"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Positive Test: Image view with VK_SAMPLE_COUNT_1_BIT should not get error 07285 in pipeline created with attachment with |
| // VK_SAMPLE_COUNT_2_BIT |
| CreatePipelineHelper dr_pipe_helper(*this); |
| dr_pipe_helper.InitInfo(); |
| dr_pipe_helper.InitState(); |
| dr_pipe_helper.gp_ci_.renderPass = VK_NULL_HANDLE; |
| dr_pipe_helper.pipe_ms_state_ci_ = ms_state; |
| dr_pipe_helper.CreateGraphicsPipeline(); |
| begin_rendering_info.pNext = nullptr; |
| color_attachment.resolveImageView = VK_NULL_HANDLE; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, dr_pipe_helper.pipeline_); |
| m_commandBuffer->Draw(1, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| color_attachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| |
| // Positive Test: Same as previous test but using render pass and should not get error 07284 |
| CreatePipelineHelper test_pipe(*this); |
| test_pipe.InitInfo(); |
| test_pipe.InitState(); |
| test_pipe.pipe_ms_state_ci_ = ms_state; |
| test_pipe.CreateGraphicsPipeline(); |
| m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, test_pipe.pipeline_); |
| m_commandBuffer->Draw(1, 1, 0, 0); |
| m_commandBuffer->EndRenderPass(); |
| |
| // Find an image format that can't be sampled |
| image_format_prop = LvlInitStruct<VkImageFormatProperties2>(); |
| image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(); |
| image_format_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_format_info.type = VK_IMAGE_TYPE_3D; |
| image_format_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| |
| VkFormat unsampleable_format = VK_FORMAT_UNDEFINED; |
| VkSampleCountFlagBits unsampleable_count = VK_SAMPLE_COUNT_1_BIT; |
| for (VkFormat format = VK_FORMAT_UNDEFINED; format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; format = VkFormat(format + 1)) { |
| image_format_info.format = format; |
| result = vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop); |
| if (result == VK_SUCCESS) { |
| if (image_format_prop.imageFormatProperties.sampleCounts != 0x7f) { |
| unsampleable_format = format; |
| for (VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; samples <= VK_SAMPLE_COUNT_64_BIT; |
| samples = VkSampleCountFlagBits(samples << 1)) { |
| if (!(image_format_prop.imageFormatProperties.sampleCounts & samples)) { |
| unsampleable_count = samples; |
| break; |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| if (unsampleable_format != VK_FORMAT_UNDEFINED) { |
| image_create_info.imageType = VK_IMAGE_TYPE_3D; |
| image_create_info.format = unsampleable_format; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; // Can't use unsupported sample count or can't create image view |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.flags = |
| VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; |
| VkImageObj unsampleable_image(m_device); |
| unsampleable_image.init(&image_create_info); |
| vk_testing::ImageView unsampleable_image_view; |
| auto unsampleable_image_view_ci = unsampleable_image.TargetViewCI(unsampleable_format); |
| unsampleable_image_view_ci.image = unsampleable_image.handle(); |
| unsampleable_image_view_ci.subresourceRange.baseMipLevel = 0; |
| unsampleable_image_view_ci.subresourceRange.levelCount = 1; |
| unsampleable_image_view.init(*m_device, unsampleable_image_view_ci); |
| begin_rendering_info.pNext = &ms_render_to_ss; |
| ms_render_to_ss.rasterizationSamples = unsampleable_count; |
| color_attachment.resolveImageView = VK_NULL_HANDLE; |
| color_attachment.imageView = unsampleable_image_view.handle(); |
| // Attachment must have a format that supports the sample count specified in rasterizationSamples |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMultisampledRenderToSingleSampledInfoEXT-pNext-06880"); |
| m_commandBuffer->BeginRendering(begin_rendering_info); |
| m_errorMonitor->VerifyFound(); |
| |
| attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| subpass.pDepthStencilAttachment = nullptr; |
| rpci.attachmentCount = 1; |
| attach_desc[0].format = unsampleable_format; |
| |
| vk_testing::RenderPass unsampleable_rp(*m_device, rpci); |
| auto unsampleable_fbci = LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, unsampleable_rp.handle(), 1u, |
| &unsampleable_image_view.handle(), 64u, 64u, 1u); |
| |
| VkFramebuffer unsampleable_fb; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-samples-07009"); |
| vk::CreateFramebuffer(m_device->device(), &unsampleable_fbci, nullptr, &unsampleable_fb); |
| m_errorMonitor->VerifyFound(); |
| attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; |
| |
| if (imageless_fb_supported) { |
| VkFormat framebufferAttachmentFormats[1] = {unsampleable_format}; |
| auto framebufferAttachmentImageInfo = LvlInitStruct<VkFramebufferAttachmentImageInfoKHR>(); |
| framebufferAttachmentImageInfo.flags = image_create_info.flags; |
| framebufferAttachmentImageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| framebufferAttachmentImageInfo.width = 64; |
| framebufferAttachmentImageInfo.height = 64; |
| framebufferAttachmentImageInfo.layerCount = 1; |
| framebufferAttachmentImageInfo.viewFormatCount = 1; |
| framebufferAttachmentImageInfo.pViewFormats = framebufferAttachmentFormats; |
| auto framebufferAttachmentsCreateInfo = LvlInitStruct<VkFramebufferAttachmentsCreateInfoKHR>(); |
| framebufferAttachmentsCreateInfo.attachmentImageInfoCount = 1; |
| framebufferAttachmentsCreateInfo.pAttachmentImageInfos = &framebufferAttachmentImageInfo; |
| rpci.attachmentCount = 1; |
| attach_desc[0].format = unsampleable_format; |
| attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| vk_testing::RenderPass imageless_rp(*m_device, rpci); |
| auto imageless_fbci = |
| LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, imageless_rp.handle(), 1u, nullptr, 64u, 64u, 1u); |
| imageless_fbci.pNext = &framebufferAttachmentsCreateInfo; |
| imageless_fbci.flags = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR; |
| vk_testing::Framebuffer imageless_fb(*m_device, imageless_fbci); |
| |
| auto renderPassAttachmentBeginInfo = LvlInitStruct<VkRenderPassAttachmentBeginInfo>(); |
| renderPassAttachmentBeginInfo.attachmentCount = 1; |
| renderPassAttachmentBeginInfo.pAttachments = &unsampleable_image_view.handle(); |
| auto renderPassBeginInfo = LvlInitStruct<VkRenderPassBeginInfo>(&renderPassAttachmentBeginInfo); |
| renderPassBeginInfo.renderPass = imageless_rp.handle(); |
| renderPassBeginInfo.renderArea.extent.width = 64; |
| renderPassBeginInfo.renderArea.extent.height = 64; |
| renderPassBeginInfo.framebuffer = imageless_fb.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassAttachmentBeginInfo-pAttachments-07010"); |
| m_commandBuffer->BeginRenderPass(renderPassBeginInfo); |
| m_errorMonitor->VerifyFound(); |
| attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; |
| } |
| } |
| |
| // Need a renderpass with a COUNT_1 attachment |
| ms_render_to_ss.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT; |
| attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| subpass.pDepthStencilAttachment = nullptr; |
| rpci.attachmentCount = 1; |
| // Create a usable renderpass |
| vk_testing::RenderPass test_rp2(*m_device, rpci); |
| auto fbci = |
| LvlInitStruct<VkFramebufferCreateInfo>(nullptr, 0u, test_rp2.handle(), 1u, &one_count_image_view.handle(), 64u, 64u, 1u); |
| VkFramebuffer fb; |
| // Framebuffer attachments with VK_SAMPLE_COUNT_1_BIT must have been created with |
| // VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFramebufferCreateInfo-samples-06881"); |
| vk::CreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; |
| image_create_info.flags = VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| VkImage bad_flag_image; |
| // VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT requires VK_SAMPLE_COUNT_1_BIT |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-flags-06883"); |
| vk::CreateImage(device(), &image_create_info, nullptr, &bad_flag_image); |
| m_errorMonitor->VerifyFound(); |
| |
| vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props); |
| auto device_create_info = LvlInitStruct<VkDeviceCreateInfo>(); |
| device_create_info.queueCreateInfoCount = queue_info.size(); |
| device_create_info.pQueueCreateInfos = queue_info.data(); |
| device_create_info.pEnabledFeatures = nullptr; |
| device_create_info.enabledExtensionCount = 0; |
| device_create_info.ppEnabledExtensionNames = nullptr; |
| |
| VkDevice second_device; |
| ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &device_create_info, nullptr, &second_device)); |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| bad_flag_image = VK_NULL_HANDLE; |
| // VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT requires multisampledRenderToSingleSampled feature |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-multisampledRenderToSingleSampled-06882"); |
| vk::CreateImage(second_device, &image_create_info, nullptr, &bad_flag_image); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyDevice(second_device, nullptr); |
| } |
| |
| TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) { |
| TEST_DESCRIPTION("Create a render pass with an attachment description format set to VK_FORMAT_UNDEFINED"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); |
| |
| VkAttachmentReference color_attach = {}; |
| color_attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| color_attach.attachment = 0; |
| VkSubpassDescription subpass = {}; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &color_attach; |
| |
| auto rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_UNDEFINED; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| rpci.pAttachments = &attach_desc; |
| |
| VkRenderPass rp; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAttachmentDescription-format-06698"); |
| vk::CreateRenderPass(m_device->device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(VkLayerTest, IncompatibleRenderPass) { |
| TEST_DESCRIPTION("Validate if attachments in render pass and descriptor set use the same image subresources"); |
| |
| ASSERT_NO_FATAL_FAILURE(Init()); |
| |
| const uint32_t width = 32; |
| const uint32_t height = 32; |
| const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkAttachmentReference attach_ref = {}; |
| attach_ref.attachment = 0; |
| attach_ref.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach_ref; |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = format; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDependency dependency = {0, |
| 0, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_DEPENDENCY_BY_REGION_BIT}; |
| |
| VkRenderPassCreateInfo rpci = LvlInitStruct<VkRenderPassCreateInfo>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| rpci.dependencyCount = 1; |
| rpci.pDependencies = &dependency; |
| |
| vk_testing::RenderPass render_pass1(*m_device, rpci); |
| rpci.dependencyCount = 0; |
| vk_testing::RenderPass render_pass2(*m_device, rpci); |
| rpci.dependencyCount = 1; |
| dependency.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
| dependency.srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; |
| vk_testing::RenderPass render_pass3(*m_device, rpci); |
| |
| VkImageObj image(m_device); |
| image.InitNoLayout(width, height, 1, format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); |
| |
| auto fb_ci = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fb_ci.renderPass = render_pass1.handle(); |
| fb_ci.attachmentCount = 1; |
| fb_ci.pAttachments = &imageView; |
| fb_ci.width = width; |
| fb_ci.height = height; |
| fb_ci.layers = 1; |
| vk_testing::Framebuffer framebuffer; |
| framebuffer.init(*m_device, fb_ci); |
| |
| VkClearValue clear_values[2] = {}; |
| clear_values[0].color = {{0, 0, 0, 0}}; |
| clear_values[1].color = {{0, 0, 0, 0}}; |
| |
| VkRenderPassBeginInfo rpbi = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbi.framebuffer = framebuffer.handle(); |
| rpbi.renderPass = render_pass2.handle(); |
| rpbi.renderArea.extent.width = width; |
| rpbi.renderArea.extent.height = height; |
| rpbi.clearValueCount = 2; |
| rpbi.pClearValues = clear_values; |
| |
| m_commandBuffer->begin(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderPass-00904"); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->VerifyFound(); |
| |
| rpbi.renderPass = render_pass3.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderPass-00904"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderPass-00904"); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(VkLayerTest, IncompatibleRenderPass2) { |
| TEST_DESCRIPTION("Validate if attachments in render pass and descriptor set use the same image subresources"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| ASSERT_NO_FATAL_FAILURE(InitFramework()); |
| if (DeviceValidationVersion() < VK_API_VERSION_1_2) { |
| GTEST_SKIP() << "At least Vulkan version 1.2 is required"; |
| } |
| |
| auto multiview_features = LvlInitStruct<VkPhysicalDeviceMultiviewFeatures>(); |
| auto features2 = GetPhysicalDeviceFeatures2(multiview_features); |
| if (multiview_features.multiview == VK_FALSE) { |
| GTEST_SKIP() << "multiview feature not supported"; |
| } |
| |
| ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2)); |
| |
| const uint32_t width = 32; |
| const uint32_t height = 32; |
| const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkAttachmentReference2 attach_ref = LvlInitStruct<VkAttachmentReference2>(); |
| attach_ref.attachment = 0; |
| attach_ref.layout = VK_IMAGE_LAYOUT_GENERAL; |
| VkSubpassDescription2 subpass = LvlInitStruct<VkSubpassDescription2>(); |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attach_ref; |
| subpass.viewMask = 0x1; |
| |
| VkAttachmentDescription2 attach_desc = LvlInitStruct<VkAttachmentDescription2>(); |
| attach_desc.format = format; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDependency2 dependency = {VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, |
| nullptr, |
| 0, |
| 0, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_DEPENDENCY_BY_REGION_BIT}; |
| |
| uint32_t correlated_view_mask = 0x1; |
| VkRenderPassCreateInfo2 rpci = LvlInitStruct<VkRenderPassCreateInfo2>(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| rpci.dependencyCount = 1; |
| rpci.pDependencies = &dependency; |
| rpci.correlatedViewMaskCount = 1; |
| rpci.pCorrelatedViewMasks = &correlated_view_mask; |
| |
| vk_testing::RenderPass render_pass1(*m_device, rpci); |
| rpci.correlatedViewMaskCount = 0; |
| vk_testing::RenderPass render_pass2(*m_device, rpci); |
| rpci.correlatedViewMaskCount = 1; |
| correlated_view_mask = 0x2; |
| vk_testing::RenderPass render_pass3(*m_device, rpci); |
| |
| VkImageObj image(m_device); |
| image.InitNoLayout(width, height, 1, format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); |
| VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); |
| |
| auto fb_ci = LvlInitStruct<VkFramebufferCreateInfo>(); |
| fb_ci.renderPass = render_pass1.handle(); |
| fb_ci.attachmentCount = 1; |
| fb_ci.pAttachments = &imageView; |
| fb_ci.width = width; |
| fb_ci.height = height; |
| fb_ci.layers = 1; |
| vk_testing::Framebuffer framebuffer; |
| framebuffer.init(*m_device, fb_ci); |
| |
| VkClearValue clear_values[2] = {}; |
| clear_values[0].color = {{0, 0, 0, 0}}; |
| clear_values[1].color = {{0, 0, 0, 0}}; |
| |
| VkRenderPassBeginInfo rpbi = LvlInitStruct<VkRenderPassBeginInfo>(); |
| rpbi.framebuffer = framebuffer.handle(); |
| rpbi.renderPass = render_pass2.handle(); |
| rpbi.renderArea.extent.width = width; |
| rpbi.renderArea.extent.height = height; |
| rpbi.clearValueCount = 2; |
| rpbi.pClearValues = clear_values; |
| |
| m_commandBuffer->begin(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderPass-00904"); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->VerifyFound(); |
| |
| rpbi.renderPass = render_pass3.handle(); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkRenderPassBeginInfo-renderPass-00904"); |
| vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |