| /* |
| * Copyright (c) 2015-2026 The Khronos Group Inc. |
| * Copyright (c) 2015-2026 Valve Corporation |
| * Copyright (c) 2015-2026 LunarG, Inc. |
| * Copyright (c) 2015-2026 Google, Inc. |
| * |
| * 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 "../framework/layer_validation_tests.h" |
| #include "../framework/sync_helper.h" |
| |
| #include "utils/image_utils.h" |
| |
| // A reasonable well supported default VkImageCreateInfo for image creation |
| VkImageCreateInfo ImageTest::DefaultImageInfo() { |
| VkImageCreateInfo ci = vku::InitStructHelper(); |
| ci.flags = 0; // assumably any is supported |
| ci.imageType = VK_IMAGE_TYPE_2D; // any is supported |
| ci.format = VK_FORMAT_R8G8B8A8_UNORM; // has mandatory support for all usages |
| ci.extent = {64, 64, 1}; // limit is 256 for 3D, or 4096 |
| ci.mipLevels = 1; // any is supported |
| ci.arrayLayers = 1; // limit is 256 |
| ci.samples = VK_SAMPLE_COUNT_1_BIT; // needs to be 1 if TILING_LINEAR |
| // if VK_IMAGE_TILING_LINEAR imageType must be 2D, usage must be TRANSFER, and levels layers samplers all 1 |
| ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; // depends on format |
| ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| return ci; |
| } |
| |
| class PositiveImage : public ImageTest {}; |
| |
| TEST_F(PositiveImage, OwnershipTransfers) { |
| TEST_DESCRIPTION("Valid image ownership transfers that shouldn't create errors"); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Queue* no_gfx_queue = m_device->QueueWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT); |
| if (!no_gfx_queue) { |
| GTEST_SKIP() << "Required queue not present (non-graphics capable required)"; |
| } else if ((m_device->Physical().queue_properties_[no_gfx_queue->family_index].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0) { |
| GTEST_SKIP() << "Non graphic queue doesn't have transfer bit"; |
| } |
| |
| vkt::CommandPool no_gfx_pool(*m_device, no_gfx_queue->family_index, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| vkt::CommandBuffer no_gfx_cb(*m_device, no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); |
| |
| // Create an "exclusive" image owned by the graphics queue. |
| VkFlags image_use = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_B8G8R8A8_UNORM, image_use); |
| auto image_subres = VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| VkImageMemoryBarrier image_barrier = vku::InitStructHelper(); |
| image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; |
| image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; |
| image_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_; |
| image_barrier.dstQueueFamilyIndex = no_gfx_queue->family_index; |
| image_barrier.image = image; |
| image_barrier.subresourceRange = image_subres; |
| |
| image.SetLayout(VK_IMAGE_LAYOUT_GENERAL); |
| |
| ValidOwnershipTransfer(m_default_queue, m_command_buffer, no_gfx_queue, no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, |
| VK_PIPELINE_STAGE_TRANSFER_BIT, nullptr, &image_barrier); |
| |
| // Change layouts while changing ownership |
| image_barrier.srcQueueFamilyIndex = no_gfx_queue->family_index; |
| image_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_; |
| image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; |
| // Make sure the new layout is different from the old |
| if (image_barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { |
| image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
| } else { |
| image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| } |
| |
| ValidOwnershipTransfer(no_gfx_queue, no_gfx_cb, m_default_queue, m_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nullptr, &image_barrier); |
| } |
| |
| TEST_F(PositiveImage, AliasedMemoryTracking) { |
| TEST_DESCRIPTION( |
| "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it"); |
| RETURN_IF_SKIP(Init()); |
| |
| VkDeviceSize buff_size = 256; |
| auto buffer = std::make_unique<vkt::Buffer>(*m_device, vkt::Buffer::CreateInfo(buff_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), |
| vkt::no_mem); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; // mandatory format |
| image_create_info.extent = {64, 64, 1}; // at least 4096x4096 is supported |
| 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.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| |
| const auto buffer_memory_requirements = buffer->MemoryRequirements(); |
| const auto image_memory_requirements = image.MemoryRequirements(); |
| |
| VkMemoryAllocateInfo alloc_info = vku::InitStructHelper(); |
| alloc_info.allocationSize = (std::max)(buffer_memory_requirements.size, image_memory_requirements.size); |
| bool has_memtype = |
| m_device->Physical().SetMemoryType(buffer_memory_requirements.memoryTypeBits & image_memory_requirements.memoryTypeBits, |
| &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); |
| if (!has_memtype) { |
| GTEST_SKIP() << "Failed to find a host visible memory type for both a buffer and an image"; |
| } |
| vkt::DeviceMemory mem(*m_device, alloc_info); |
| |
| auto pData = mem.Map(); |
| std::memset(pData, 0xCADECADE, static_cast<size_t>(buff_size)); |
| mem.Unmap(); |
| |
| buffer->BindMemory(mem, 0); |
| |
| // NOW, destroy the buffer. Obviously, the resource no longer occupies this |
| // memory. In fact, it was never used by the GPU. |
| // Just be sure, wait for idle. |
| buffer.reset(nullptr); |
| m_device->Wait(); |
| |
| image.BindMemory(mem, 0); |
| } |
| |
| TEST_F(PositiveImage, CreateImageViewFollowsParameterCompatibilityRequirements) { |
| TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors."); |
| RETURN_IF_SKIP(Init()); |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| vkt::Image image(*m_device, image_ci, vkt::set_layout); |
| image.CreateView(); |
| } |
| |
| TEST_F(PositiveImage, BasicUsage) { |
| TEST_DESCRIPTION("Verify that we can create a view with usage INPUT_ATTACHMENT"); |
| RETURN_IF_SKIP(Init()); |
| vkt::Image image(*m_device, 128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); |
| vkt::ImageView view = image.CreateView(); |
| } |
| |
| TEST_F(PositiveImage, FormatCompatibility) { |
| TEST_DESCRIPTION("Test format compatibility"); |
| AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat format = VK_FORMAT_R12X4G12X4_UNORM_2PACK16; |
| |
| VkImageFormatListCreateInfo format_list = vku::InitStructHelper(); |
| format_list.viewFormatCount = 1; |
| format_list.pViewFormats = &format; |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(&format_list); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.extent = {32, 32, 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_SAMPLED_BIT; |
| image_create_info.flags = 0; |
| vkt::Image image(*m_device, image_create_info); |
| } |
| |
| TEST_F(PositiveImage, MultpilePNext) { |
| TEST_DESCRIPTION( |
| "Use VkImageFormatListCreateInfo and VkImageCompressionControlEXT to make sure internal " |
| "DispatchGetPhysicalDeviceImageFormatProperties2 pass them along"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| const VkFormat view_format = VK_FORMAT_R8G8B8A8_UINT; |
| |
| VkImageFormatListCreateInfo format_list = vku::InitStructHelper(); |
| format_list.viewFormatCount = 1; |
| format_list.pViewFormats = &view_format; |
| |
| VkImageCompressionControlEXT image_compression = vku::InitStructHelper(&format_list); |
| image_compression.compressionControlPlaneCount = 0; |
| image_compression.flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT; |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(&image_compression); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.extent = {32, 32, 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_COLOR_ATTACHMENT_BIT; |
| image_create_info.flags = 0; |
| |
| vkt::Image(*m_device, image_create_info); |
| } |
| |
| TEST_F(PositiveImage, FramebufferFrom3DImage) { |
| TEST_DESCRIPTION("Validate creating a framebuffer from a 3D image."); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_ci.extent = {32, 32, 4}; |
| 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; |
| vkt::Image image(*m_device, image_ci, vkt::set_layout); |
| |
| VkImageViewCreateInfo dsvci = vku::InitStructHelper(); |
| dsvci.image = image; |
| dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| dsvci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| dsvci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4}; |
| vkt::ImageView view(*m_device, dsvci); |
| |
| VkFramebufferCreateInfo fci = vku::InitStructHelper(); |
| fci.renderPass = m_renderPass; |
| fci.attachmentCount = 1; |
| fci.pAttachments = &view.handle(); |
| fci.width = 32; |
| fci.height = 32; |
| fci.layers = 4; |
| vkt::Framebuffer fb(*m_device, fci); |
| } |
| |
| TEST_F(PositiveImage, ExtendedUsageWithDifferentFormatViews) { |
| TEST_DESCRIPTION("Create views with different formats of an image with extended usage"); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = |
| VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| image_ci.format = VK_FORMAT_BC3_UNORM_BLOCK; |
| image_ci.extent = { |
| 64, // width |
| 64, // height |
| 1, // depth |
| }; |
| 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_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| |
| VkImageFormatProperties image_properties; |
| VkResult err = GetImageFormatProps(Gpu(), image_ci, image_properties); |
| if (err != VK_SUCCESS) { |
| GTEST_SKIP() << "Image format not valid for format, type, tiling, usage and flags combination."; |
| } |
| |
| vkt::Image image(*m_device, image_ci); |
| ASSERT_TRUE(image != VK_NULL_HANDLE); |
| |
| // Since the format is compatible with all image's usage, there's no need to restrict usage |
| VkImageViewCreateInfo iv_ci = vku::InitStructHelper(); |
| iv_ci.image = image; |
| iv_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| iv_ci.format = VK_FORMAT_R32G32B32A32_UINT; |
| iv_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| vkt::ImageView view(*m_device, iv_ci); |
| ASSERT_TRUE(view != VK_NULL_HANDLE); |
| |
| // Since usage is inherited from the image, we need to restrict the usage to a subset |
| // Compressed images do not support storage, but we want to sample from the compressed |
| VkImageViewUsageCreateInfo ivu_ci = vku::InitStructHelper(); |
| ivu_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| iv_ci.pNext = &ivu_ci; |
| vkt::ImageView view2(*m_device, iv_ci); |
| ASSERT_TRUE(view2 != VK_NULL_HANDLE); |
| } |
| |
| TEST_F(PositiveImage, ImageCompressionControl) { |
| TEST_DESCRIPTION("Checks for creating fixed rate compression image."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| |
| AddRequiredExtensions(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::imageCompressionControl); |
| RETURN_IF_SKIP(Init()); |
| |
| // Query possible image format with vkGetPhysicalDeviceImageFormatProperties2KHR |
| VkPhysicalDeviceImageFormatInfo2 image_format_info = vku::InitStructHelper(); |
| image_format_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_format_info.tiling = VK_IMAGE_TILING_LINEAR; |
| image_format_info.type = VK_IMAGE_TYPE_2D; |
| image_format_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| |
| VkImageCompressionPropertiesEXT compression_properties = vku::InitStructHelper(); |
| VkImageFormatProperties2 image_format_properties = vku::InitStructHelper(&compression_properties); |
| |
| vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_format_info, &image_format_properties); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(1, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, |
| VK_IMAGE_TILING_LINEAR); |
| |
| // Create with disabled image compression |
| { |
| VkImageCompressionControlEXT compressionControl = vku::InitStructHelper(); |
| compressionControl.flags = VK_IMAGE_COMPRESSION_DISABLED_EXT; |
| image_ci.pNext = &compressionControl; |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| |
| // Create with default image compression, without fixed rate |
| { |
| VkImageCompressionControlEXT compressionControl = vku::InitStructHelper(); |
| compressionControl.flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT; |
| image_ci.pNext = &compressionControl; |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| |
| // Create with fixed rate compression image |
| { |
| VkImageCompressionControlEXT compressionControl = vku::InitStructHelper(); |
| compressionControl.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT; |
| image_ci.pNext = &compressionControl; |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| |
| // Create with fixed rate compression image |
| if (compression_properties.imageCompressionFixedRateFlags != VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT) { |
| VkImageCompressionFixedRateFlagsEXT supported_compression_fixed_rate = VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT; |
| |
| for (uint32_t index = 0; index < 32; index++) { |
| if ((compression_properties.imageCompressionFixedRateFlags & (1 << index)) != 0) { |
| supported_compression_fixed_rate = (1 << index); |
| break; |
| } |
| } |
| |
| ASSERT_TRUE(supported_compression_fixed_rate != VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT); |
| |
| VkImageCompressionFixedRateFlagsEXT fixedRageFlags = supported_compression_fixed_rate; |
| VkImageCompressionControlEXT compressionControl = vku::InitStructHelper(); |
| compressionControl.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT; |
| compressionControl.pFixedRateFlags = &fixedRageFlags; |
| compressionControl.compressionControlPlaneCount = 1; |
| image_ci.pNext = &compressionControl; |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| } |
| |
| TEST_F(PositiveImage, Create3DImageView) { |
| TEST_DESCRIPTION("Create a 3D image view"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo ci = vku::InitStructHelper(); |
| ci.imageType = VK_IMAGE_TYPE_3D; |
| ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| ci.extent = {32, 32, 8}; |
| ci.mipLevels = 6; |
| ci.arrayLayers = 1; |
| ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
| ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, ci, vkt::set_layout); |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_3D); |
| } |
| |
| TEST_F(PositiveImage, SlicedCreateInfo) { |
| TEST_DESCRIPTION("Test VkImageViewSlicedCreateInfoEXT"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::imageSlicedViewOf3D); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo ci = vku::InitStructHelper(); |
| ci.imageType = VK_IMAGE_TYPE_3D; |
| ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| ci.extent = {32, 32, 8}; |
| ci.mipLevels = 6; |
| ci.arrayLayers = 1; |
| ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
| ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, ci, vkt::set_layout); |
| |
| VkImageViewSlicedCreateInfoEXT sliced_info = vku::InitStructHelper(); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(&sliced_info); |
| ivci.image = image; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_3D; |
| ivci.format = ci.format; |
| ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.layerCount = 1; |
| |
| auto get_effective_depth = [&]() -> uint32_t { |
| return GetEffectiveExtent(ci, ivci.subresourceRange.aspectMask, ivci.subresourceRange.baseMipLevel).depth; |
| }; |
| |
| { |
| sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ASSERT_TRUE(get_effective_depth() == 8); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT; |
| sliced_info.sliceOffset = 1; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ASSERT_TRUE(get_effective_depth() == 8); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = 8; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ASSERT_TRUE(get_effective_depth() == 8); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = 4; |
| sliced_info.sliceOffset = 4; |
| ivci.subresourceRange.baseMipLevel = 0; |
| ASSERT_TRUE(get_effective_depth() == 8); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = 4; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.baseMipLevel = 1; |
| ASSERT_TRUE(get_effective_depth() == 4); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = 2; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.baseMipLevel = 2; |
| ASSERT_TRUE(get_effective_depth() == 2); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; |
| ivci.subresourceRange.baseMipLevel = 5; |
| ASSERT_TRUE(get_effective_depth() == 1); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| { |
| sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT; |
| sliced_info.sliceOffset = 0; |
| ivci.subresourceRange.levelCount = 1; |
| ivci.subresourceRange.baseMipLevel = 5; |
| ASSERT_TRUE(get_effective_depth() == 1); |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| } |
| |
| TEST_F(PositiveImage, BlockTexelViewCompatibleMultipleLayers) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_6_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance6); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance6PropertiesKHR maintenance6_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance6_props); |
| if (!maintenance6_props.blockTexelViewCompatibleMultipleLayers) { |
| GTEST_SKIP() << "blockTexelViewCompatibleMultipleLayers is not enabled"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 4; |
| image_create_info.arrayLayers = 2; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| |
| VkFormatProperties image_fmt; |
| vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), image_create_info.format, &image_fmt); |
| if (!vkt::Image::IsCompatible(*m_device, image_create_info.usage, image_fmt.optimalTilingFeatures)) { |
| GTEST_SKIP() << "Image usage and format not compatible on device"; |
| } |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = image; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| ivci.format = VK_FORMAT_R16G16B16A16_UNORM; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; |
| vkt::ImageView view(*m_device, ivci); |
| } |
| |
| TEST_F(PositiveImage, ImageFormatListSizeCompatibleUncompressed) { |
| AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| const VkFormat formats[1] = {VK_FORMAT_R32G32B32A32_UINT}; |
| VkImageFormatListCreateInfo format_list = vku::InitStructHelper(nullptr); |
| format_list.viewFormatCount = 1; |
| format_list.pViewFormats = formats; |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_USAGE_SAMPLED_BIT); |
| image_ci.pNext = &format_list; |
| image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT; |
| |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Image create info not supported on device"; |
| } |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| |
| TEST_F(PositiveImage, ImageFormatListSizeCompatibleCompressed) { |
| AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| const VkFormat formats[2] = {VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK}; |
| VkImageFormatListCreateInfo format_list = vku::InitStructHelper(nullptr); |
| format_list.viewFormatCount = 2; |
| format_list.pViewFormats = formats; |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_USAGE_SAMPLED_BIT); |
| image_ci.pNext = &format_list; |
| image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT; |
| |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Image create info not supported on device"; |
| } |
| |
| vkt::Image image(*m_device, image_ci); |
| } |
| |
| TEST_F(PositiveImage, ImageAlignmentControl) { |
| AddRequiredExtensions(VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::imageAlignmentControl); |
| RETURN_IF_SKIP(Init()); |
| |
| const uint32_t alignment = 0x1; |
| VkPhysicalDeviceImageAlignmentControlPropertiesMESA props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(props); |
| if (!(props.supportedImageAlignmentMask & alignment)) { |
| GTEST_SKIP() << "supportedImageAlignmentMask doesn't support testing alignment"; |
| } |
| VkImageAlignmentControlCreateInfoMESA alignment_control = vku::InitStructHelper(); |
| alignment_control.maximumRequestedAlignment = alignment; |
| |
| VkImageCreateInfo image_create_info = DefaultImageInfo(); |
| image_create_info.pNext = &alignment_control; |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| } |
| |
| TEST_F(PositiveImage, ImageAlignmentControlZero) { |
| AddRequiredExtensions(VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::imageAlignmentControl); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageAlignmentControlCreateInfoMESA alignment_control = vku::InitStructHelper(); |
| alignment_control.maximumRequestedAlignment = 0; // Should ignore |
| |
| VkImageCreateInfo image_create_info = DefaultImageInfo(); |
| image_create_info.pNext = &alignment_control; |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| } |
| |
| TEST_F(PositiveImage, RemainingMipLevels2DViewOf3D) { |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT; |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32, 32, 2}; |
| 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_INPUT_ATTACHMENT_BIT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, image_ci, vkt::set_layout); |
| |
| vkt::ImageView view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0, VK_REMAINING_MIP_LEVELS, 0, 1); |
| } |
| |
| TEST_F(PositiveImage, RemainingMipLevelsBlockTexelView) { |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 2; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| |
| if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Image create info not compatible on device"; |
| } |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = image; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| ivci.format = VK_FORMAT_R16G16B16A16_UNORM; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, 1}; |
| vkt::ImageView view(*m_device, ivci); |
| } |
| |
| TEST_F(PositiveImage, BlitMaintenance8) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::maintenance8); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_8_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat format = VK_FORMAT_R32_SFLOAT; // Need features ..BLIT_SRC_BIT & ..BLIT_DST_BIT |
| |
| if (!FormatFeaturesAreSupported(Gpu(), format, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) { |
| GTEST_SKIP() << "No blit feature format support"; |
| } |
| |
| VkImageCreateInfo ci = vku::InitStructHelper(); |
| ci.imageType = VK_IMAGE_TYPE_3D; |
| ci.format = format; |
| ci.extent = {64, 64, 8}; |
| ci.mipLevels = 1; |
| ci.arrayLayers = 1; |
| ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| vkt::Image image_3d(*m_device, ci); |
| |
| ci.imageType = VK_IMAGE_TYPE_2D; |
| ci.extent.depth = 1; |
| ci.arrayLayers = 4; |
| vkt::Image image_2d(*m_device, ci); |
| |
| // src is 2D with multiple layers |
| VkImageBlit blit_region = {}; |
| blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1}; |
| blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| blit_region.srcOffsets[0] = {0, 0, 0}; |
| blit_region.srcOffsets[1] = {16, 16, 1}; |
| blit_region.dstOffsets[0] = {32, 32, 0}; |
| blit_region.dstOffsets[1] = {64, 64, 1}; |
| |
| m_command_buffer.Begin(); |
| vk::CmdBlitImage(m_command_buffer, image_2d, VK_IMAGE_LAYOUT_GENERAL, image_3d, VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, |
| VK_FILTER_NEAREST); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(PositiveImage, ImageViewIncompatibleFormat) { |
| TEST_DESCRIPTION("Tests for VUID-VkImageViewCreateInfo-image-01761"); |
| // original issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2203 |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| vkt::Image mutImage(*m_device, image_ci, vkt::set_layout); |
| |
| VkImageViewCreateInfo imgViewInfo = vku::InitStructHelper(); |
| imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| imgViewInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| imgViewInfo.image = mutImage; |
| |
| // With a identical format, there should be no error |
| imgViewInfo.format = image_ci.format; |
| vkt::ImageView image_view(*m_device, imgViewInfo); |
| |
| vkt::Image mut_compat_image(*m_device, image_ci); |
| |
| imgViewInfo.image = mut_compat_image; |
| imgViewInfo.format = VK_FORMAT_R8_SINT; // different, but size compatible |
| vkt::ImageView image_view2(*m_device, imgViewInfo); |
| } |
| |
| TEST_F(PositiveImage, BlockTexelViewType) { |
| TEST_DESCRIPTION( |
| "Create Image with VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT and non-compressed format and ImageView with view type " |
| "VK_IMAGE_VIEW_TYPE_3D."); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| image_create_info.imageType = VK_IMAGE_TYPE_3D; |
| image_create_info.format = VK_FORMAT_BC1_RGBA_SRGB_BLOCK; |
| image_create_info.extent = {32, 32, 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_SAMPLED_BIT; |
| |
| if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Image create info not compatible on device"; |
| } |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = image; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_3D; |
| ivci.format = VK_FORMAT_R16G16B16A16_UNORM; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| } |
| |
| TEST_F(PositiveImage, CornerSampledImageNV) { |
| TEST_DESCRIPTION("Test VK_NV_corner_sampled_image."); |
| AddRequiredExtensions(VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::cornerSampledImage); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.extent = {2, 1, 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_TRANSFER_DST_BIT; |
| image_create_info.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV; |
| |
| { |
| // Valid # of mip levels |
| image_create_info.extent = {7, 7, 1}; |
| image_create_info.mipLevels = 3; // 3 = ceil(log2(7)) |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| } |
| { |
| image_create_info.extent = {8, 8, 1}; |
| image_create_info.mipLevels = 3; // 3 = ceil(log2(8)) |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| } |
| { |
| image_create_info.extent = {9, 9, 1}; |
| image_create_info.mipLevels = 3; // 4 = ceil(log2(9)) |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| } |
| } |
| |
| TEST_F(PositiveImage, ArrayViewAndSparseFlags) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_9_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::sparseBinding); |
| AddRequiredFeature(vkt::Feature::maintenance9); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance9PropertiesKHR maintenance9_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance9_props); |
| if (!maintenance9_props.image2DViewOf3DSparse) { |
| GTEST_SKIP() << "image2DViewOf3DSparse is not supported"; |
| } |
| |
| VkImageCreateInfo create_info = vku::InitStructHelper(); |
| create_info.flags = VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT; |
| create_info.imageType = VK_IMAGE_TYPE_3D; |
| create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| create_info.extent = {32u, 32u, 1u}; |
| create_info.mipLevels = 1u; |
| create_info.arrayLayers = 1u; |
| create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| |
| vkt::Image(*m_device, create_info, vkt::no_mem); |
| } |
| |
| TEST_F(PositiveImage, Image3DWith2DArrayCompatIssue) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32, 32, 2}; |
| 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_TRANSFER_DST_BIT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, image_ci); |
| |
| VkImageMemoryBarrier image_memory_barrier = vku::InitStructHelper(); |
| image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; |
| image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; |
| image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
| image_memory_barrier.image = image; |
| image_memory_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, VK_REMAINING_ARRAY_LAYERS}; |
| |
| m_command_buffer.Begin(); |
| vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, |
| nullptr, 1, &image_memory_barrier); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(PositiveImage, ImageView2dOf3dBaseLayer) { |
| TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10416"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_9_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT; |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32u, 32u, 2u}; |
| image_ci.mipLevels = 1u; |
| image_ci.arrayLayers = 1u; |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, image_ci); |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0u, 1u, 1u, 1u); |
| } |
| |
| TEST_F(PositiveImage, FramebufferRemainingArrayLayers) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_ci.extent = {32u, 32u, 5u}; |
| image_ci.mipLevels = 1u; |
| image_ci.arrayLayers = 1u; |
| 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; |
| vkt::Image image(*m_device, image_ci); |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0u, 1u, 2u, VK_REMAINING_ARRAY_LAYERS); |
| |
| VkFramebufferCreateInfo fb_ci = vku::InitStructHelper(); |
| fb_ci.renderPass = m_renderPass; |
| fb_ci.attachmentCount = 1u; |
| fb_ci.pAttachments = &image_view.handle(); |
| fb_ci.width = 32u; |
| fb_ci.height = 32u; |
| fb_ci.layers = 1u; |
| vkt::Framebuffer framebuffer(*m_device, fb_ci); |
| } |
| |
| TEST_F(PositiveImage, BlockTexelViewLayerCount) { |
| TEST_DESCRIPTION("Create view with VK_REMAINING_ARRAY_LAYERS layerCount from CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE image"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| RETURN_IF_SKIP(Init()); |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | |
| VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| image_create_info.imageType = VK_IMAGE_TYPE_3D; |
| image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK; |
| image_create_info.extent = {32, 32, 2}; |
| 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_SAMPLED_BIT; |
| |
| if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { |
| GTEST_SKIP() << "Image create info not compatible on device"; |
| } |
| vkt::Image image(*m_device, image_create_info); |
| |
| VkImageViewCreateInfo image_view_ci = vku::InitStructHelper(); |
| image_view_ci.image = image; |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| image_view_ci.format = VK_FORMAT_R16G16B16A16_UNORM; |
| image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; |
| |
| // Test that VK_REMAINING_ARRAY_LAYERS evaluates to 1 |
| vkt::ImageView view(*m_device, image_view_ci); |
| } |
| |
| TEST_F(PositiveImage, ImageSingleLayerDescriptorFlagButMultiplanarImageView) { |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_11_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance11); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| RETURN_IF_SKIP(Init()); |
| |
| auto image_ci = |
| vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.flags |= VK_IMAGE_CREATE_ALIAS_SINGLE_LAYER_DESCRIPTOR_BIT_KHR | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| |
| VkImageFormatProperties props; |
| if (VK_SUCCESS != GetImageFormatProps(Gpu(), image_ci, props)) { |
| GTEST_SKIP() << "Image not supported"; |
| } |
| |
| vkt::Image image(*m_device, image_ci); |
| VkImageViewCreateInfo image_view_ci = vku::InitStructHelper(); |
| image_view_ci.image = image; |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| image_view_ci.format = VK_FORMAT_R8_UNORM; |
| image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_PLANE_0_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS}; |
| vkt::ImageView view(*m_device, image_view_ci); |
| } |