Edit

kc3-lang/angle/src/tests/gl_tests/VulkanFormatTablesTest.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2021-01-08 17:29:42
    Hash : 2e9706d8
    Message : Vulkan: Use angle::FormatID instead of VkFormat. This change switches the internal enums we pass around from VkFormat to FormatID. The end goal of the refactor is to allow the Vulkan back-end to store packed tables indexed by FormatID. Because VkFormat has large gaps in its enum space we'd otherwise need to use unordered data structures like unordered_map. The change removes the redundant VkFormat storage from vk::Format and uses a new table query to return the VkFormat that 1:1 matches an angle::FormatID. We also include a reverse mapping for use with native Vulkan get functions for Android. Also moves sRGB conversion functions into renderer_utils. A couple sRGB formats that don't exist in GL are no longer handled by the sRGB conversion functions. These formats should be extremely rare. Bug: angleproject:5438 Change-Id: Id8b49773ca0c556f9f5a6a10fcf0d9762b93bbea Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2618204 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Ian Elliott <ianelliott@google.com>

  • src/tests/gl_tests/VulkanFormatTablesTest.cpp
  • //
    // Copyright 2018 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // VulkanFormatTablesTest:
    //   Tests to validate our Vulkan support tables match hardware support.
    //
    
    #include "test_utils/ANGLETest.h"
    #include "test_utils/angle_test_instantiate.h"
    // 'None' is defined as 'struct None {};' in
    // third_party/googletest/src/googletest/include/gtest/internal/gtest-type-util.h.
    // But 'None' is also defined as a numeric constant 0L in <X11/X.h>.
    // So we need to include ANGLETest.h first to avoid this conflict.
    
    #include "libANGLE/Context.h"
    #include "libANGLE/angletypes.h"
    #include "libANGLE/formatutils.h"
    #include "libANGLE/renderer/vulkan/ContextVk.h"
    #include "libANGLE/renderer/vulkan/RendererVk.h"
    #include "util/EGLWindow.h"
    
    using namespace angle;
    
    namespace
    {
    
    class VulkanFormatTablesTest : public ANGLETest
    {};
    
    struct ParametersToTest
    {
        VkImageType imageType;
        VkImageCreateFlags createFlags;
    };
    
    // This test enumerates all GL formats - for each, it queries the Vulkan support for
    // using it as a texture, filterable, and a render target. It checks this against our
    // speed-optimized baked tables, and validates they would give the same result.
    TEST_P(VulkanFormatTablesTest, TestFormatSupport)
    {
        ASSERT_TRUE(IsVulkan());
    
        // Hack the angle!
        const gl::Context *context = static_cast<gl::Context *>(getEGLWindow()->getContext());
        auto *contextVk            = rx::GetImplAs<rx::ContextVk>(context);
        rx::RendererVk *renderer   = contextVk->getRenderer();
    
        // We need to test normal 2D images as well as Cube images.
        const std::vector<ParametersToTest> parametersToTest = {
            {VK_IMAGE_TYPE_2D, 0}, {VK_IMAGE_TYPE_2D, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT}};
    
        const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
        for (GLenum internalFormat : allFormats)
        {
            const rx::vk::Format &vkFormat = renderer->getFormat(internalFormat);
    
            // Similar loop as when we build caps in vk_caps_utils.cpp, but query using
            // vkGetPhysicalDeviceImageFormatProperties instead of vkGetPhysicalDeviceFormatProperties
            // and verify we have all the same caps.
            if (!vkFormat.valid())
            {
                // TODO(jmadill): Every angle format should be mapped to a vkFormat.
                // This hasn't been defined in our vk_format_map.json yet so the caps won't be filled.
                continue;
            }
    
            const gl::TextureCaps &textureCaps = renderer->getNativeTextureCaps().get(internalFormat);
    
            for (const ParametersToTest params : parametersToTest)
            {
                VkFormat actualImageVkFormat =
                    rx::vk::GetVkFormatFromFormatID(vkFormat.actualImageFormatID);
    
                // Now let's verify that against vulkan.
                VkFormatProperties formatProperties;
                vkGetPhysicalDeviceFormatProperties(renderer->getPhysicalDevice(), actualImageVkFormat,
                                                    &formatProperties);
    
                VkImageFormatProperties imageProperties;
    
                // isTexturable?
                bool isTexturable =
                    vkGetPhysicalDeviceImageFormatProperties(
                        renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
                        VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, params.createFlags,
                        &imageProperties) == VK_SUCCESS;
                EXPECT_EQ(isTexturable, textureCaps.texturable) << actualImageVkFormat;
    
                // TODO(jmadill): Support ES3 textures.
    
                // isFilterable?
                bool isFilterable = (formatProperties.optimalTilingFeatures &
                                     VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ==
                                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
                EXPECT_EQ(isFilterable, textureCaps.filterable) << actualImageVkFormat;
    
                // isRenderable?
                const bool isRenderableColor =
                    (vkGetPhysicalDeviceImageFormatProperties(
                        renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
                        VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
                        params.createFlags, &imageProperties)) == VK_SUCCESS;
                const bool isRenderableDepthStencil =
                    (vkGetPhysicalDeviceImageFormatProperties(
                        renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
                        VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
                        params.createFlags, &imageProperties)) == VK_SUCCESS;
    
                bool isRenderable = isRenderableColor || isRenderableDepthStencil;
                EXPECT_EQ(isRenderable, textureCaps.textureAttachment) << actualImageVkFormat;
                EXPECT_EQ(isRenderable, textureCaps.renderbuffer) << actualImageVkFormat;
            }
        }
    }
    
    ANGLE_INSTANTIATE_TEST(VulkanFormatTablesTest, ES2_VULKAN());
    
    }  // anonymous namespace