xref: /aosp_15_r20/external/angle/src/tests/gl_tests/VulkanFormatTablesTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // VulkanFormatTablesTest:
7 //   Tests to validate our Vulkan support tables match hardware support.
8 //
9 
10 #include "libANGLE/Context.h"
11 #include "libANGLE/Display.h"
12 #include "libANGLE/angletypes.h"
13 #include "libANGLE/formatutils.h"
14 #include "libANGLE/renderer/vulkan/ContextVk.h"
15 #include "libANGLE/renderer/vulkan/vk_renderer.h"
16 #include "test_utils/ANGLETest.h"
17 #include "test_utils/angle_test_instantiate.h"
18 #include "util/EGLWindow.h"
19 
20 using namespace angle;
21 
22 namespace
23 {
24 
25 class VulkanFormatTablesTest : public ANGLETest<>
26 {};
27 
28 struct ParametersToTest
29 {
30     VkImageType imageType;
31     VkImageCreateFlags createFlags;
32 };
33 
34 // This test enumerates all GL formats - for each, it queries the Vulkan support for
35 // using it as a texture, filterable, and a render target. It checks this against our
36 // speed-optimized baked tables, and validates they would give the same result.
TEST_P(VulkanFormatTablesTest,TestFormatSupport)37 TEST_P(VulkanFormatTablesTest, TestFormatSupport)
38 {
39     ASSERT_TRUE(IsVulkan());
40 
41     // Hack the angle!
42     egl::Display *display   = static_cast<egl::Display *>(getEGLWindow()->getDisplay());
43     gl::ContextID contextID = {
44         static_cast<GLuint>(reinterpret_cast<uintptr_t>(getEGLWindow()->getContext()))};
45     gl::Context *context       = display->getContext(contextID);
46     auto *contextVk            = rx::GetImplAs<rx::ContextVk>(context);
47     rx::vk::Renderer *renderer = contextVk->getRenderer();
48 
49     // We need to test normal 2D images as well as Cube images.
50     const std::vector<ParametersToTest> parametersToTest = {
51         {VK_IMAGE_TYPE_2D, 0}, {VK_IMAGE_TYPE_2D, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT}};
52 
53     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
54     for (GLenum internalFormat : allFormats)
55     {
56         const rx::vk::Format &vkFormat = renderer->getFormat(internalFormat);
57 
58         // Similar loop as when we build caps in vk_caps_utils.cpp, but query using
59         // vkGetPhysicalDeviceImageFormatProperties instead of vkGetPhysicalDeviceFormatProperties
60         // and verify we have all the same caps.
61         if (!vkFormat.valid())
62         {
63             // TODO(jmadill): Every angle format should be mapped to a vkFormat.
64             // This hasn't been defined in our vk_format_map.json yet so the caps won't be filled.
65             continue;
66         }
67 
68         const gl::TextureCaps &textureCaps = renderer->getNativeTextureCaps().get(internalFormat);
69 
70         for (const ParametersToTest params : parametersToTest)
71         {
72             VkFormat actualImageVkFormat = rx::vk::GetVkFormatFromFormatID(
73                 renderer, vkFormat.getActualImageFormatID(rx::vk::ImageAccess::SampleOnly));
74 
75             // Now let's verify that against vulkan.
76             VkFormatProperties formatProperties;
77             vkGetPhysicalDeviceFormatProperties(renderer->getPhysicalDevice(), actualImageVkFormat,
78                                                 &formatProperties);
79 
80             VkImageFormatProperties imageProperties;
81 
82             // isTexturable?
83             bool isTexturable =
84                 vkGetPhysicalDeviceImageFormatProperties(
85                     renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
86                     VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, params.createFlags,
87                     &imageProperties) == VK_SUCCESS;
88             EXPECT_EQ(isTexturable, textureCaps.texturable) << actualImageVkFormat;
89 
90             // TODO(jmadill): Support ES3 textures.
91 
92             // isFilterable?
93             bool isFilterable = (formatProperties.optimalTilingFeatures &
94                                  VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ==
95                                 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
96             EXPECT_EQ(isFilterable, textureCaps.filterable) << actualImageVkFormat;
97 
98             // isRenderable?
99             VkFormat actualRenderableImageVkFormat = rx::vk::GetVkFormatFromFormatID(
100                 renderer, vkFormat.getActualRenderableImageFormatID());
101             const bool isRenderableColor =
102                 (vkGetPhysicalDeviceImageFormatProperties(
103                     renderer->getPhysicalDevice(), actualRenderableImageVkFormat, params.imageType,
104                     VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
105                     params.createFlags, &imageProperties)) == VK_SUCCESS;
106             const bool isRenderableDepthStencil =
107                 (vkGetPhysicalDeviceImageFormatProperties(
108                     renderer->getPhysicalDevice(), actualRenderableImageVkFormat, params.imageType,
109                     VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
110                     params.createFlags, &imageProperties)) == VK_SUCCESS;
111 
112             bool isRenderable = isRenderableColor || isRenderableDepthStencil;
113             EXPECT_EQ(isRenderable, textureCaps.textureAttachment) << actualImageVkFormat;
114             EXPECT_EQ(isRenderable, textureCaps.renderbuffer) << actualImageVkFormat;
115         }
116     }
117 }
118 
119 ANGLE_INSTANTIATE_TEST(VulkanFormatTablesTest, ES2_VULKAN());
120 
121 }  // anonymous namespace
122