blob: 1ccced063b0482729f0dfed4ac4b522dcb402ee6 [file] [log] [blame]
/*
* Copyright (c) 2023 Valve Corporation
* Copyright (c) 2023 LunarG, 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 "generated/vk_extension_helper.h"
#include "utils/vk_layer_utils.h"
class PositiveLayerUtils : public VkPositiveLayerTest {};
// These test check utils in the layer without needing to create a full Vulkan instance
TEST_F(PositiveLayerUtils, GetEffectiveExtent) {
TEST_DESCRIPTION("Test unlikely GetEffectiveExtent edge cases");
VkImageCreateInfo ci = vku::InitStructHelper();
VkExtent3D extent = {};
// Return zero extent if mip level doesn't exist
{
ci.mipLevels = 0;
ci.extent = {1, 1, 1};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
ASSERT_TRUE(extent.width == 0);
ASSERT_TRUE(extent.height == 0);
ASSERT_TRUE(extent.depth == 0);
ci.mipLevels = 1;
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
ASSERT_TRUE(extent.width == 0);
ASSERT_TRUE(extent.height == 0);
ASSERT_TRUE(extent.depth == 0);
}
// Check that 0 based extent is respected
{
ci.flags = 0;
ci.imageType = VK_IMAGE_TYPE_3D;
ci.mipLevels = 2;
ci.extent = {0, 0, 0};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
ASSERT_TRUE(extent.width == 0);
ASSERT_TRUE(extent.height == 0);
ASSERT_TRUE(extent.depth == 0);
ci.extent = {16, 32, 0};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
ASSERT_TRUE(extent.width == 8);
ASSERT_TRUE(extent.height == 16);
ASSERT_TRUE(extent.depth == 0);
}
// Corner sampled images
{
ci.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV;
ci.imageType = VK_IMAGE_TYPE_3D;
ci.mipLevels = 2;
ci.extent = {1, 1, 1};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
// The minimum level size is 2x2x2 for 3D corner sampled images.
ASSERT_TRUE(extent.width == 2);
ASSERT_TRUE(extent.height == 2);
ASSERT_TRUE(extent.depth == 2);
ci.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV;
ci.imageType = VK_IMAGE_TYPE_3D;
ci.mipLevels = 2;
ci.extent = {4, 8, 16};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 1);
ASSERT_TRUE(extent.width == 2);
ASSERT_TRUE(extent.height == 4);
ASSERT_TRUE(extent.depth == 8);
ci.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV;
ci.imageType = VK_IMAGE_TYPE_3D;
ci.mipLevels = 3;
ci.extent = {8, 16, 32};
extent = GetEffectiveExtent(ci, VK_IMAGE_ASPECT_NONE, 2);
ASSERT_TRUE(extent.width == 2);
ASSERT_TRUE(extent.height == 4);
ASSERT_TRUE(extent.depth == 8);
}
}
TEST_F(PositiveLayerUtils, IsOnlyOneValidPlaneAspect) {
const VkFormat two_plane_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM;
ASSERT_FALSE(IsOnlyOneValidPlaneAspect(two_plane_format, 0));
ASSERT_FALSE(IsOnlyOneValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_COLOR_BIT));
ASSERT_TRUE(IsOnlyOneValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT));
ASSERT_FALSE(IsOnlyOneValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT));
ASSERT_FALSE(IsOnlyOneValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT));
ASSERT_FALSE(IsOnlyOneValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_2_BIT));
}
TEST_F(PositiveLayerUtils, IsValidPlaneAspect) {
const VkFormat two_plane_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM;
ASSERT_FALSE(IsValidPlaneAspect(two_plane_format, 0));
ASSERT_FALSE(IsValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_COLOR_BIT));
ASSERT_TRUE(IsValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT));
ASSERT_TRUE(IsValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT));
ASSERT_FALSE(IsValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT));
ASSERT_FALSE(IsValidPlaneAspect(two_plane_format, VK_IMAGE_ASPECT_PLANE_2_BIT));
}
TEST_F(PositiveLayerUtils, IsMultiplePlaneAspect) {
ASSERT_FALSE(IsMultiplePlaneAspect(0));
ASSERT_FALSE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_COLOR_BIT));
ASSERT_FALSE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_PLANE_0_BIT));
ASSERT_TRUE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT));
ASSERT_TRUE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT));
ASSERT_TRUE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT));
ASSERT_FALSE(IsMultiplePlaneAspect(VK_IMAGE_ASPECT_PLANE_2_BIT));
}
TEST_F(PositiveLayerUtils, IsImageLayoutDepthOnly) {
ASSERT_TRUE(IsImageLayoutDepthOnly(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL));
ASSERT_TRUE(IsImageLayoutDepthOnly(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL));
ASSERT_TRUE(IsImageLayoutDepthOnly(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR));
ASSERT_TRUE(IsImageLayoutDepthOnly(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR));
constexpr std::array all_layouts_but_depth_only{
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
// VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
// VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR,
VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR, VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR, VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT, VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR,
#endif
VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV,
// VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR,
// VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR,
VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR,
VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_MAX_ENUM};
for (auto layout : all_layouts_but_depth_only) {
ASSERT_FALSE(IsImageLayoutDepthOnly(layout));
}
}
TEST_F(PositiveLayerUtils, IsImageLayoutStencilOnly) {
ASSERT_TRUE(IsImageLayoutStencilOnly(VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL));
ASSERT_TRUE(IsImageLayoutStencilOnly(VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL));
ASSERT_TRUE(IsImageLayoutStencilOnly(VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR));
ASSERT_TRUE(IsImageLayoutStencilOnly(VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR));
constexpr std::array all_layouts_but_stencil_only{
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
// VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
// VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR, VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR, VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,
VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR,
#endif
VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR,
// VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR,
// VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR,
VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_MAX_ENUM};
for (auto layout : all_layouts_but_stencil_only) {
ASSERT_FALSE(IsImageLayoutStencilOnly(layout));
}
}