1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
gpu / vulkan / drm_modifiers_filter_vulkan_unittest.cc [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include <vulkan/vulkan_core.h>
#include <memory>
#include "gpu/vulkan/drm_modifiers_filter_vulkan.h"
#include "gpu/vulkan/init/vulkan_factory.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/buffer_types.h"
namespace gpu {
namespace {
const uint64_t kSupportedModifier1 = 1;
const uint64_t kSupportedModifier2 = 2;
const uint64_t kUnsupportedModifier = 3;
const std::vector<uint64_t> kSupportedModifiers = {kSupportedModifier1,
kSupportedModifier2};
} // namespace
class DrmModifiersFilterVulkanTest : public testing::Test {
public:
DrmModifiersFilterVulkanTest() = default;
DrmModifiersFilterVulkanTest(const DrmModifiersFilterVulkanTest&) = delete;
DrmModifiersFilterVulkanTest& operator=(const DrmModifiersFilterVulkanTest&) =
delete;
~DrmModifiersFilterVulkanTest() override = default;
void SetUp() override {
vulkan_impl_ = CreateVulkanImplementation();
if (!vulkan_impl_ ||
!vulkan_impl_->InitializeVulkanInstance(false /* using_surface */)) {
// Some test platforms like linux-chromeos-rel advertise Vulkan support
// but do not support 1.1. vkGetPhysicalDeviceFormatProperties as used
// below is part of 1.1 which causes Vulkan initialization (and the test)
// to fail.
GTEST_SKIP() << "Unable to initialize Vulkan";
}
filter_ = std::make_unique<DrmModifiersFilterVulkan>(vulkan_impl_.get());
// Chrome's Vulkan interface doesn't have mock bindings yet, so as a
// workaround we just overwrite the pointers.
gpu::VulkanFunctionPointers* ptrs = gpu::GetVulkanFunctionPointers();
cached_vk_fn_ = ptrs->vkGetPhysicalDeviceFormatProperties2.get();
ptrs->vkGetPhysicalDeviceFormatProperties2.OverrideForTesting(
[](VkPhysicalDevice p, VkFormat f, VkFormatProperties2* out) {
EXPECT_NE(nullptr, out);
EXPECT_NE(nullptr, out->pNext);
auto* modifiers =
static_cast<VkDrmFormatModifierPropertiesListEXT*>(out->pNext);
EXPECT_EQ(VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
modifiers->sType);
if (!modifiers->pDrmFormatModifierProperties) {
modifiers->drmFormatModifierCount = kSupportedModifiers.size();
return;
}
EXPECT_EQ(kSupportedModifiers.size(),
modifiers->drmFormatModifierCount);
for (size_t i = 0; i < kSupportedModifiers.size(); i++) {
auto& modifier = modifiers->pDrmFormatModifierProperties[i];
modifier.drmFormatModifier = kSupportedModifiers[i];
modifier.drmFormatModifierPlaneCount = 1;
modifier.drmFormatModifierTilingFeatures = 0;
}
});
}
void TearDown() override {
filter_.reset();
if (cached_vk_fn_) {
gpu::VulkanFunctionPointers* ptrs = gpu::GetVulkanFunctionPointers();
ptrs->vkGetPhysicalDeviceFormatProperties2.OverrideForTesting(
cached_vk_fn_);
}
}
protected:
std::unique_ptr<VulkanImplementation> vulkan_impl_;
std::unique_ptr<DrmModifiersFilterVulkan> filter_;
PFN_vkGetPhysicalDeviceFormatProperties2 cached_vk_fn_;
};
TEST_F(DrmModifiersFilterVulkanTest, FilterUnsupported) {
std::vector<uint64_t> all_modifiers = {kSupportedModifier1,
kUnsupportedModifier};
std::vector<uint64_t> filtered_modifiers =
filter_->Filter(gfx::BufferFormat::BGRX_8888, all_modifiers);
EXPECT_EQ(1u, filtered_modifiers.size());
EXPECT_EQ(kSupportedModifier1, filtered_modifiers[0]);
}
} // namespace gpu