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