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 "test_utils/ANGLETest.h"
11 #include "test_utils/angle_test_instantiate.h"
12 // 'None' is defined as 'struct None {};' in
13 // third_party/googletest/src/googletest/include/gtest/internal/gtest-type-util.h.
14 // But 'None' is also defined as a numeric constant 0L in <X11/X.h>.
15 // So we need to include ANGLETest.h first to avoid this conflict.
16
17 #include "libANGLE/Context.h"
18 #include "libANGLE/angletypes.h"
19 #include "libANGLE/formatutils.h"
20 #include "libANGLE/renderer/vulkan/ContextVk.h"
21 #include "libANGLE/renderer/vulkan/RendererVk.h"
22 #include "util/EGLWindow.h"
23
24 using namespace angle;
25
26 namespace
27 {
28
29 class VulkanFormatTablesTest : public ANGLETest
30 {};
31
32 struct ParametersToTest
33 {
34 VkImageType imageType;
35 VkImageCreateFlags createFlags;
36 };
37
38 // This test enumerates all GL formats - for each, it queries the Vulkan support for
39 // using it as a texture, filterable, and a render target. It checks this against our
40 // speed-optimized baked tables, and validates they would give the same result.
TEST_P(VulkanFormatTablesTest,TestFormatSupport)41 TEST_P(VulkanFormatTablesTest, TestFormatSupport)
42 {
43 ASSERT_TRUE(IsVulkan());
44
45 // Hack the angle!
46 const gl::Context *context = static_cast<gl::Context *>(getEGLWindow()->getContext());
47 auto *contextVk = rx::GetImplAs<rx::ContextVk>(context);
48 rx::RendererVk *renderer = contextVk->getRenderer();
49
50 // We need to test normal 2D images as well as Cube images.
51 const std::vector<ParametersToTest> parametersToTest = {
52 {VK_IMAGE_TYPE_2D, 0}, {VK_IMAGE_TYPE_2D, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT}};
53
54 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
55 for (GLenum internalFormat : allFormats)
56 {
57 const rx::vk::Format &vkFormat = renderer->getFormat(internalFormat);
58
59 // Similar loop as when we build caps in vk_caps_utils.cpp, but query using
60 // vkGetPhysicalDeviceImageFormatProperties instead of vkGetPhysicalDeviceFormatProperties
61 // and verify we have all the same caps.
62 if (!vkFormat.valid())
63 {
64 // TODO(jmadill): Every angle format should be mapped to a vkFormat.
65 // This hasn't been defined in our vk_format_map.json yet so the caps won't be filled.
66 continue;
67 }
68
69 const gl::TextureCaps &textureCaps = renderer->getNativeTextureCaps().get(internalFormat);
70
71 for (const ParametersToTest params : parametersToTest)
72 {
73 VkFormat actualImageVkFormat =
74 rx::vk::GetVkFormatFromFormatID(vkFormat.actualImageFormatID);
75
76 // Now let's verify that against vulkan.
77 VkFormatProperties formatProperties;
78 vkGetPhysicalDeviceFormatProperties(renderer->getPhysicalDevice(), actualImageVkFormat,
79 &formatProperties);
80
81 VkImageFormatProperties imageProperties;
82
83 // isTexturable?
84 bool isTexturable =
85 vkGetPhysicalDeviceImageFormatProperties(
86 renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
87 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, params.createFlags,
88 &imageProperties) == VK_SUCCESS;
89 EXPECT_EQ(isTexturable, textureCaps.texturable) << actualImageVkFormat;
90
91 // TODO(jmadill): Support ES3 textures.
92
93 // isFilterable?
94 bool isFilterable = (formatProperties.optimalTilingFeatures &
95 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ==
96 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
97 EXPECT_EQ(isFilterable, textureCaps.filterable) << actualImageVkFormat;
98
99 // isRenderable?
100 const bool isRenderableColor =
101 (vkGetPhysicalDeviceImageFormatProperties(
102 renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
103 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
104 params.createFlags, &imageProperties)) == VK_SUCCESS;
105 const bool isRenderableDepthStencil =
106 (vkGetPhysicalDeviceImageFormatProperties(
107 renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
108 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
109 params.createFlags, &imageProperties)) == VK_SUCCESS;
110
111 bool isRenderable = isRenderableColor || isRenderableDepthStencil;
112 EXPECT_EQ(isRenderable, textureCaps.textureAttachment) << actualImageVkFormat;
113 EXPECT_EQ(isRenderable, textureCaps.renderbuffer) << actualImageVkFormat;
114 }
115 }
116 }
117
118 ANGLE_INSTANTIATE_TEST(VulkanFormatTablesTest, ES2_VULKAN());
119
120 } // anonymous namespace
121